3

I want to receive a list of fields from a field set, and then query a list of records with those fields. At last, i want to show the data in a lightning web component.

I have the following function that retrieves a list of fields from a field set:

@AuraEnabled(cacheable=true) 
public static Map<String,String> getFieldsFromFieldSet(String sobjectType, String fieldSetApiName) {
    List<String> fieldsApiNames = new List<String>();

    List<Schema.FieldSetMember> fieldSetMemberList =  Schema.getGlobalDescribe().get(sobjectType).getDescribe().FieldSets.getMap().get(fieldSetApiName).getFields();
    for(Schema.FieldSetMember fieldSetMemberObj : fieldSetMemberList) {
        fieldsApiNames.add(fieldSetMemberObj.getFieldPath());
    }

    Map<String,String> fieldsMap = new Map<String,String>();
    if(fieldsApiNames.Size() > 0 ) {
        for(String field : fieldsApiNames) {
            fieldsMap.put(field,field);
        }
    }
    return fieldsMap;
}

js

@wire(getFieldsFromFieldSet, {sobjectType: 'Asset', fieldSetApiName :'License_Site_Asset_Fields'})
wiredProductsFields({data, error}) {
    if(data) {
        for(let key in data) {
            // Preventing unexcepted data
            if (data.hasOwnProperty(key)) { // Filtering the data in the loop
                //this.mapOfValues.push({value:data[key], key:key});
                this.ProductsFieldsMap.push({key: key, value: data[key]});
            }
        }
    }
    else if(error) {
        window.console.log(error);
    }
}

now i have the list of fields in the property ProductsFieldsMap.

Next, i want to run another wire, pass the related record id and those fields, and query a related record.

@AuraEnabled(cacheable=true) 
public static Asset[] getAssets(Map<String,String> fieldsMap,Id recordId) {
    string fields = '';
    for(String field : fieldsMap.values()) {
        fields += field + ', ';
    }
    fields = fields.removeEnd(', ');

    string query = 'SELECT ' + fields + ' FROM Asset WHERE License__c =:recordId LIMIT 10';
    return Database.query(query);
}

How can i pass the fields to the second function? im receiving null in the parameter fieldsMap. Is there a way to chain those @wire functions?

And how can i show the records in a record view form without knowing the fields in advance?

2 Answers 2

2

Option 1: (preferred)

I do not see a reason why you need fields information in LWC javascript. This is actually overhead as you need 2 transactions for getting fields info and then querying the records. Instead you can do as below in 1 transaction: (using getAssets apex method and pass required parameters needed for getFieldsFromFieldSet also)

@AuraEnabled(cacheable=true) 
public static Asset[] getAssets(String sobjectType, String fieldSetApiName, Id recordId) {
    Map<String, String> fieldsMap = getFieldsFromFieldSet(sobjectType, fieldSetApiName);
    string fields = '';
    for(String field : fieldsMap.values()) {
        fields += field + ', ';
    }
    fields = fields.removeEnd(', ');

    string query = 'SELECT ' + fields + ' FROM Asset WHERE License__c =:recordId LIMIT 10';
    return Database.query(query);
}

Option 2: If you need fields in JS by any chance you can use dynamic property ProductsFieldsMap to initialise another wire.

@wire(getAssets, { fieldsMap: '$ProductsFieldsMap', recordId: '$recordId' })
wiredAssets({ data, error }) {
    if (data) {
        // data
    }
    else if (error) {
        // window.console.log(error);
    }
}

Whenever ProductsFieldsMap or recordId changes, above wired service gets invoked. So, when ProductsFieldsMap is set in 1st wire, this wire will be invoked and you get records in data

2
  • Don't i need those fields if i want to show the record i got from the query in a record view form?
    – Dana Griff
    Commented Oct 16, 2019 at 11:37
  • You will need in view form. But for the scenario in question does not need. However, option 2 as I have mentioned above will work in that case Commented Oct 16, 2019 at 11:52
-1

It seems to me that you are not passing a map to your second apex function.

Can you try the following? Also, how are you calling your 'getAssets' apex function in LWC?

@wire(getFieldsFromFieldSet, {sobjectType: 'Asset', fieldSetApiName :'License_Site_Asset_Fields'})
wiredProductsFields({data, error}) {
    if(data) {
        this.ProductsFieldsMap = {};
        for(let key in data) {
            // Preventing unexcepted data
            if (data.hasOwnProperty(key)) { // Filtering the data in the loop
                //this.mapOfValues.push({value:data[key], key:key});
                this.ProductsFieldsMap[key] = data[key];
            }
        }
    }
    else if(error) {
        window.console.log(error);
    }
}
1
  • i wasn't able to implement the call to getAssets. That's exactly my question how. However, there is a value of a map inside ProductsFieldsMap.
    – Dana Griff
    Commented Oct 16, 2019 at 10:53

You must log in to answer this question.

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