My Apex controller returns a map<Account, list<String>>
map type to my Lightning JS controller. But when I access it in my component's JS controller, the map turns into an object!
This unwanted conversion creates a few issues:
-
Map methods like
mapName.keys()
don't work. -
The object isn't iterable, eg with
for(var [key, value] of myMap.entries()
-
In JS, unlike maps, objects can only have strings/symbols as keys. Which explains why my Apex map's sObject keys are now strings!
When I just retrieve a list of sObjects in my component controller, they are successfully stored as an object array, with the appropriate notation/syntax, ie:
{Id: "012345678912345", Name: "ABC Co"}
But in this former-map-turned-object, the sObject key has been stringified into something I can't use JSON.parse()
on, ie:
[Account (Id:012345678912345, Name:ABC Co)]
Which is strange because according to this doc,
Return results from a server-side controller to a client-side controller using the return statement. Results data must be serializable into JSON format.
What am I missing here?
Best Answer
JSON and ES6 Maps just don’t play well together. You basically cannot natively deserialise a Apex controller returned JSON into a Map. If you want to iterate over the keys in the JS object you could just use the
for(key in o)
syntaxIn the above JS snippet the variable
jsObject
is NOT an ES6 Map. It can only be deserialised to a plain JS object. The reverse is also NOT possible.JSON.stringify()
on a ES6 Map won't do any thing. i.e. you cannot serialise an ES6 Map to a JSON because of the obvious reason that Object keys have to be strings and a Map key can be any Object.Also, on the server side, Apex Map JSON serialisation is only supported when the Keys are primitive data types. See the last bullet point in Apex Map considerations in the docs
In summary you are doing the following 2 things Wrong
Mark's Answer is a good way to work around point 1