1

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?

3
  • So instead of an array of objects, you're going to be building up an object whose properties are objects. Simple enough, but I don't think you've indicated what you're planning to use as keys on the top-level object ...? – Matthew Souther Dec 30 '20 at 16:40
  • Yeah, for example, if before the array of objects was something like this: [{value : 'something'}, {value: 'something'}, {}, {}, etc] now, i want it to be {nameOfFilter1: {value: 'something'}, nameOfFilter2 : {value : 'something'}, etc, etc}. The keys will be the names of the filters, specified in the data-name attribute in the html – joacoiudica Dec 30 '20 at 16:50
  • In the filter I used as an example, "Status" would be the key, so: {Status: {value : 'someValue'}} – joacoiudica Dec 30 '20 at 16:53
1

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.

1
  • Thank you! Your solution is actually better, I'm new to programming so the info is very welcome. Thanks again – joacoiudica Dec 30 '20 at 17:55
1

I resolved it by doing this:

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

The assignFilterName function:

assignFilterName(filter){
    let obj = {};
    let name = filter.dataset.name;
    obj = {[name] : filter.exportData()};
    return obj;
}

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.