2

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?

1

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

  • 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 Oct 16 '19 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 – salesforce-sas Oct 16 '19 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);
    }
}
  • 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 Oct 16 '19 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.