[SalesForce] exporting a map> from lwc js module to apex

This javascript method builds an array of objects:

handleSearch(){
    let data = [...this.template.querySelectorAll('c-lwc-filter')]
                .map(filter => filter.exportData());
    console.log(JSON.stringify(data));
    this.filtersData = data;
}

And I pass it via wire to this apex method:

@AuraEnabled(cacheable=true)
public static List<Item__c> importFilters(List<Map<String, Object>> fltrs){
    QueryFilters q = getFilters();
    String query;
    for(Integer i = 0; i < q.filters.size(); i++){
        q.filters[i].import(fltrs[i]);
    }
    query = QueryFilters.build('select id from Item__c', q.filters) + 'LIMIT 50';
    return Database.query(query);
}

It receives a List<Map<String, Object>> so I build an array of objects. Now, I changed the last method, to receive a Map<String, Map<String, Object>> instead:

@AuraEnabled(cacheable=true)
public static List<Item__c> importFilters(Map<String, Map<String, Object>> fltrs){
    QueryFilters q= getFilters();
    String query;
    for(String key : fltrs.keySet()){
        q.namedFilters.get(key).import(fltrs.get(key));
    }
    query = QueryFilters.build('select id from Item__c', q.namedFilters) + 'LIMIT 50';
    return Database.query(query); 
}

So you can have a little context on this, what I'm doing is importing filters, with values so that I can build a query and fetch records. Now I changed it so the filters are named, and are rendered like this:

<lightning-layout-item padding="around-small" size="3">
        <c-lwc-filter filter={filters.Status} data-name="Status"></c-lwc-filter>
</lightning-layout-item>

(There are several lwc-filter components rendering, not only that one. That is why I do a querySelectorAll in the js)

How do I modify my handleSearch method, to add the data-name value to the map<string, map<string, object>> i want to pass it to apex?

Best Answer

Your answer works fine. I was just about to reply with a similar but slightly more succinct answer, so here it is anyway:

handleSearch() {
    let data = {};
    [...this.template.querySelectorAll("c-lwc-filter")].forEach(filter => {
        data[filter.dataset.name] = filter.exportData();
    });
    this.filtersData = data;
}

You could also consider using the reduce() function on arrays instead of a map() or forEach(). That's just a matter of preference.

Related Topic