10

I have a aura map attribute defined in my component file as below

<aura:attribute name="FilesNameMap" type="Map">

But i am not able to understand how to iterate this in the component file as we know that the < aura:iteration > will work on List but not for Map.

Below is the code which i tried to iterate the Map but couldn't succeed.

 <aura:iteration items="{!v.FilesNameMap}" indexVar="key" var="item">
                    //- logic                   
 </ aura:iteration>

Please let me know how can i iterate the Map in Aura component to fetch key and value pairs.

Thanks.

  • Looks like you have to add quite a lot of boiler-plate if this How to iterate map in Salesfore Lightning? example is typical. Looks like it would be worth doing more work in the Apex controller to avoid the situation, particularly as AFAIK there is no build-in way to test the JavaScript in Lightning. – Keith C Sep 7 '16 at 7:43
5

Pretty much all browsers support the JavaScript method Object.keys() which takes in an object and returns an array of just its keys. So you could have a second attribute of type String[] and set it in the controller equal to Object.keys(theMapYouWantToIterate). A bit more troublesome though is the fact that you can't actually look up that index of the map in Aura binding notation (e.g {!v.myMap[key]} doesn't work).

So if you need to iterate and use both the name and values, you might alternatively want to pass it to the controller as a list of objects (i.e. Map[]) where each object has a name and a value. If you have no choice but to start with a map in the controller, you can transform it to a list of objects something like this: var listOfObjects = Object.keys(myMap).map(function(key){return {name: key, value: myMap[key]} }).

0

For what it's worth, the way I solved this is by creating a list of JS objects, which had the value of my key as one attribute, and then had a list representing the items that were in that key.

This way, you can use aura:interation for your map by first doing an aura:interation on the outside object (the key), and then doing a nested aura:iteration on the list (the keys contents).


To explain my use case, I needed to get a list of sObjects back from SF, but I needed them grouped based on the value of a field. Normally you could create an Map<String, List<sObject>> for something like that, but aura:iteration doesn't work with maps.

So what I did instead was have the apex return just a list....

@AuraEnabled
public static List<myCustomObj__c> apex_myCustomObjs(String accountId) {
    List<myCustomObj__c> objList = new List<myCustomObj__c>();
    for(myCustomObj__c myObj: [SELECT Id, someField__c, someOtherField__c FROM myCustomObj__c WHERE Account__c = :accountId]) {
        objList.add(myObj);
    }
    return objList;
}

And in my component controller, I do the to take this list and compile it into something like a map...

// Go and call my apex class...
var myAction = component.get('c.apex_myCustomObjs');
myAction.setParams({
    "accountId": someVariableWhereYouHaveAnId
});
// Handle returned results...
myAction.setCallback(this, function(response) {
    var state = response.getState();
    if(component.isValid() && state === "SUCCESS") {
        var result = response.getReturnValue();

        // Place to store our list of objects
        // This will be an array of JS objects that look like:
        // { "key": "some value", "list": [{ ... }] }
        // ...where "list" is your list of items in that key
        var myObjectMap = [];

        // Loop through results; remember, this is a list of sObjects
        for(var i=0; i<result.length; i++) {
            // Get the record
            var myRecord = result[i];
            // Pull out the field that's going to be my key
            var myKey = myRecord.someField__c

            // Keep track of whether our key already exists in myObjectMap
            var found = false;
            // Loop through our map and see if an entry for our key exists
            for(var x=0; x<myObjectMap.length; x++) {
                // Look to see if our object has a "key" value
                // and whether that key is equal to the key we want
                // to use to group everything
                if("key" in myObjectMap[x] && myObjectMap[x]["key"] == myKey) {
                    myObjectMap[x]["list"].push(myRecord);
                    // We found our key and pushed the record into its
                    // list, no need to continue
                    found = true;
                    break;
                }
            }
            // Need to make sure this record found a home; if it didn't
            // then we need to initialize it in our "map"
            if(!found) {
                var temp = { "key": myKey, "list": [myRecord] };
                myObjectMap.push(temp);
            }
        }

        component.set('v.listOfMyCustomObject', myObjectMap);

        /*
        At the end of all this, myObjectMap should look something like...
        [
            {
                "key": "value 1"
                , "list": [
                    {
                        ...json representation of myCustomObj__c...
                    }
                    , {
                        ....another record...
                    }
                ]
            }
            , {
                "key": "value 2"
                , "list": [
                    {
                        ...another record...
                    }
                ]
            }
        ];

        */
    } else {
        // error handling
    }
});

Now that you've got that, you'll iterate twice in your component over these two lists, one on the external list and the other inside...

<aura:attribute name="listOfMyCustomObject" type="object[]" default="[]" />

<aura:iteration items="{!v.listOfMyCustomObject}" var="outside">
    <h1>{!outside.key}</h1>
    <ul>
    <aura:iteration items="{!outside.list}" var="inside">
        <li>{!inside.someField__c} - {!inside.someOtherField__c}</li>
    </aura:iteration>
    </ul>
</aura:iteration>

Now, that was my use case, which might not fit yours.

The main thing is that aura:iteration only uses Lists/Arrays, so if you can figure out what you need to do to turn your map into a list of lists, then the above should hopefully point you towards a solution.

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.