3

Sometimes I see code using the SObject type as an aura:attribute type and I don't see why!

<aura:attribute type="Account" ..

It feels like it behaves the same as "Map", it's just a javascript object like {}, and the most times I don't even know if I am supposed to add a namespace for packaged objects, since it doesn't give any feedback if I'm doing it wrong. I guess I should though.

I would prefer just using Map, to not confuse the framework or pretend having a type that doesn't even exist.

So what are the advantages of using the SObject type instead of Map?

And where is this documented? It's not part of the documented basic types.

  • To my knowledge it just adds the sObjectType property to the attribute - which is used for casting at the apex controller level. I am assuming they will add more functionality later on - like validation rules. Docs: developer.salesforce.com/docs/atlas.en-us.lightning.meta/… – Christian Szandor Knapp Apr 27 '18 at 9:23
  • When you retrieve SObjects from the server, this attribute is already set, so it works with map too. And if you set the value of you object it doesn't add this value, so you have to add it yourself, what is the same for maps.. Thanks for the doc, to bad they didn't add some explanation :( – Basti Apr 27 '18 at 10:34
3

There could be several reasons other than what I am describing here . But here is one for starters. I recently faced a challenge when I was using aura:attribute of type Map in IE11.

I was sending this map to apex controllers for a DML operation as follows.

Component

<aura:attribute name="sampleMap" type="Map" />

Controller

var myMap = new Map();
myMap['Account'] = { Name : "Test Account"};
myMap['Contact'] = { LastName : "Baron"};
component.set("v.sampleMap",myMap);
var action = component.get("c.serverEcho");
action.setParams({ jsMap : component.get("v.itemMap") });
action.setCallback(this, function(response) {});
$A.enqueueAction(action);

This is an expando method of assigning properties to type Map in javascript and is a valid one when trying to assign dynamic properties to a map/object. Also as you can see I got greedy.

But I ran into issues where I was able to see some extra key : value pairs being added to the Map thus resulting in an Internal server error when trying to perform a DML operation in the apex side.

Looks like IE/aura/closure-compiler(not sure which one) adds certain key-value pairs when using expando properties. You would see something as follows when you debug the incoming values inside apex class.

{_i={}, _s=0, _t=Map, Account={Name=Test Account}, Contact={lastName=Baron}}

If you do not sanitize the keys before performing the DML operation. Then there is a good chance you will run into errors. So I had to sanitize the inputs before I sent it to the apex as follows

sanitizeMap : function(myMap) {
    for(var key in myMap){
        if(this.startsWith(key,"_",0)){
            delete myMap[key]; 
        }
    }
    return myMap;
},

startsWith : function(haystack,needle, position) {
    position = position || 0;
    return haystack.indexOf(needle, position) === position;
}

As you see from the code above, this code assumes the properties are going to start with a "_" and if the properties change there is a good chance that these sanitization checks might not work.

Point being - Javascript Map as such is not a strict type and using SObject Type in lightning component and inside the apex controller could save you a ton of time doing sanitization checks for any unseen values introduced during the runtime (might not happen always). Also, it is always better using the typed attributes rather than untyped attributes as it improves the code readability and maintainability over a long run.

  • 3
    For a similar reason, I always send back JSON serialized Object back from Apex controller, convert them into Javascript Object and use it in Attribute. Solves most of the issues in IE. – Pranay Jaiswal Apr 27 '18 at 9:28
  • Exactly. Also, there are a few other issues with Maps ( Weakmaps do not work well with IE ) – StormBr34ker Apr 27 '18 at 9:34
  • Wish they had discarded IE in 2017. I hate extended support, they gonna now support it till 2020. More pain for devs. – Pranay Jaiswal Apr 27 '18 at 9:35
  • we are not supporting IE ;) and with map I always use just the regular js object structure let x = {a: 1}; so I didn't run into these issues. – Basti Apr 27 '18 at 10:18

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.