2

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 ...? Commented Dec 30, 2020 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 Commented Dec 30, 2020 at 16:50
  • In the filter I used as an example, "Status" would be the key, so: {Status: {value : 'someValue'}} Commented Dec 30, 2020 at 16:53

2 Answers 2

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 Commented Dec 30, 2020 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;
}

You must log in to answer this question.

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