Lightning Web Components – LWC Wire Service Firing Twice

lightning-web-componentswire

Can someone explain to me if it is normal for the wire service to be called twice in the javascript below. The javascript is below and is added to the account record page. I am also posting a screenshot of the console logs that I posted. For the account that I ran this on, there were NO related records. So I'm also a little confused about why the code got inside the if(data) in the wire if the apex class returned no records? Thanks!

Here is the console.log results:

1 Im in the wire
3 here is cas in the cas variableundefined
1 Im in the wire
2 Im in the if data
3 here is cas in the cas variable[]

Here is the js:

import { LightningElement, wire, api, track } from "lwc";
import getcas from "@salesforce/apex/LwcMainController.getCa";

//actions available in data-table
const actions = [{ label: "Show details", name: "show_details" }];
//variable to hold columns
const columns = [
  {
    label: "Actions",
    type: "action",
    fixedWidth: 90,
    fixedHeight: 90,
    typeAttributes: {
      rowActions: actions,
      // menuAlignment: 'auto'
    },
  },
  {
    label: "Name",
    fieldName: "Name",
    sortable: "true",
    initialWidth: 400,
    cellAttributes: {
      class: { fieldName: "activeClass" },
    },
  },
  {
    label: "Start Date",
    fieldName: "Start_Date__c",
    type: "date-local",
    sortable: "true",
    initialWidth: 150,
    cellAttributes: {
      class: { fieldName: "activeClass" },
    },
  },
  {
    label: "End Date",
    fieldName: "End_Date__c",
    type: "date-local",
    sortable: "true",
    initialWidth: 150,
    cellAttributes: {
      class: { fieldName: "activeClass" },
    },
  },
];
export default class TestRecordList extends LightningElement {
  @track data;
  @track columns = columns;
  @api recordId;
  @track cas = undefined;
  //used to hold entire wire.. needed for refreshApex
  @track casResponse = [];

  //wire to pull down the Horizon Products used for creating Opp Products
  @wire(getcas, { accountId: "$recordId" })
  wiredRecords(response) {
    console.log("1 Im in the wire");
    const { data, error } = response;
    if (data) {
      console.log("2 Im in the if data");
      //set variable indicating we have fired this wire
      this.data = data;

      // set the activeClass for css and assign records to es variable
      let activeClass = "activeRecords";
      // Process record data
      this.cas = data;
      this.showCa = true;
    } else if (error) {
      this.error = error;
      this.cas = undefined;
      this.data = undefined;
    }
    console.log("3 here is cas in the cas variable" + JSON.stringify(this.cas));
  } //end of wire
}

Best Answer

Wire methods always fire twice initially. The first provides no data but ensures that you won't have an undefined variable at the top level. The second time it fires is immediately after it receives data (or generates an error). In other words, response in your code will not be null/undefined but will have nothing in the error/data properties. This is useful for code that uses getFieldValue:

get accountName() {
  return getFieldValue(this.account.data, ACCOUNT_NAME);
}

Without this initial pulse of data, we'd be forced to check an extra null/undefined:

get accountName() {
  return this.account && getFieldValue(this.account.data, ACCOUNT_NAME);
}

Remember that "no" data is still "some" data (it should be an empty list, versus a null value). Null means that a value is "unknown", while an empty list means that the value is known, and that value has no content.

Related Topic