1

I'm having trouble using @wire for example to get a single field from an object detail and passing it in to the async connected callback for a query. I need to get some data from a related list on another table and am wondering if I could achieve this with the out of the box lwc stuff or if I am gonna have to write some more specific apex logic to handle the query. I'm reading through the docs and seeing something to the effect of wrapping both method wire? I also have auraEnabled(cacheable=true) to run it on mount(?). The code is something like:

import { LightningElement, api, track, wire } from 'lightning';
import LOOKUP_FIELD from '@salesforce/schema/Account.Lookup__c';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import getData from '@salesforce/apex/Util.getData';

const fields = [ LOOKUP_FIELD ];
export default class TestComponent extends LightningElement {
  @api recordId;
  @track data;
  @wire( getRecord, { recordId:`$recordId`, fields } )
  account; // happens later

  async connectedCallback() {
    // happens first
    const lookup = this.lookup;
    this.data = await getData({ lookup }).catch(err => console.log(err));
  }

  get lookup() {
    return getFieldValue(this.account.data, LOOKUP_FIELD);
  }

}

2
  • Looks like ` return getFieldValue(this.account.data, LOOKUP_FIELD);` will be null as you don't have account yet. Oct 15, 2019 at 21:25
  • Yeah it's undefined, I'm just wondering how to architect this or if it is even possible to get the single field from the record detail to use in some logic. Oct 16, 2019 at 2:11

2 Answers 2

1

Wire function is asynchronously invoked by LWC framwork and you have no control/reference over it. And connectedCallback is synchronously invoked on component init.

You should be using wired function and not wired property to achieve your use case - because you have dependent logic on the returned data from wired getRecord.

@wire(getRecord, { recordId: '$recordId', fields })
wiredAccount({ data, error }) {
    if (data) {
        this.account = data;
        const lookup = this.account.fields.Lookup__c.value;
        this.someOtherData = getData({ lookup }).catch(err => console.log(err));
    } else if (error) {
        console.error('ERROR ', error);
    }
}

Note that your parameters for getRecord function are wrong. Its not record, its recordId, also check the syntax.

1
  • This makes sense and was exactly what I was looking for. It looks a lot simpler too than the implementation I made. Fixed the typo. Oct 16, 2019 at 18:17
0

You can hook up a function to receive the result of an @wire - which means you should be able to call the other code sequentially:

export default class TestComponent extends LightningElement {
  @api recordId;
  @track data;
  @track account;
  _lookup;

  @track
  get lookup() {
      return this._lookup;
  }
  set lookup(value) {
     this._lookup = value;
  }  

  @wire( getFieldValue, { record:'$recordId', fields: FIELDS } )
  wiredAccount({ error, data }) {
      if (data) {
          this.account = data;
          this.lookup = getFieldValue(this.account.data, LOOKUP_FIELD);
          this.data = await getData({ this.lookup }).catch(err => console.log(err));
      } else if (error) {
      //do something
      }
}

Note, there is no need for the getter and setter on lookup - but I left them in as you already had a getter there... perhaps you were needing for something else.

1
  • I was trying not to use a 'getter' or 'setter' as I figured there was a way to do it as answered above with less attributes. I see about the private attribute notation '_lookup'; this is good practice to follow too and I will use it. Thanks for the responses! Oct 16, 2019 at 18:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .