4

I'm pulling my hair out trying to figure out how to properly encode parsable JSON as a Lightning Component default attribute value.

Strangely this example works just fine within the Lightning Components itself:

<aura:attribute name="items" type="Object[]" default="[ { headerLabel: 'Header 1', subItems: [ { label: 'Item 1', active: true, url: '#' }, { label: 'Item 2', url: '#' } ] }, { headerLabel: 'Header 2', subItems: [ { label: 'Item 3', url: '#' }, { label: 'Item 4', url: '#' } ] } ]" />

I can use items in my Lightning Component, such as in the following example, and it reads the data just fine:

<aura:iteration items="{!v.items}" var="item"> ... </aura:iteration>

However, if I try to read the the attribute in my component controller, and parse as JSON, it doesn't parse. This is understandable, as the string is not in a valid JSON format. But, one cannot format the string in a valid JSON format in the component markup, as it causes syntax errors.

A simpler example is this:

<aura:component implements="forceCommunity:availableForAllPageTypes" access="global" >

    <aura:attribute name="item" type="Object" default="{ name: 'Chuck'}" />

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <h1>{!v.item.name}</h1>

</aura:component>

With the controller being this:

({
    doInit : function(component, event, helper) {
        var jsonString = component.get('v.item');

        // OUTPUTS: JSON String: { name: 'Chuck'}
        console.log('JSON String: ' + jsonString);

        // OUTPUTS: JSON name: undefined
        console.log('JSON name: ' + jsonString.name);

        // THIS LINE WILL CAUSE ERRORS:
        console.log('JSON: ' + JSON.parse(jsonString));
    }
})

Firstly, <h1>{!v.item.name}</h1> outputs nothing at all, which I cannot explain. The attribute should be parsing this as an object, but nothing returns via <h1>{!v.item.name}</h1>.

I'm confused as to why my more complex code example, utilizing Object[] works just fine but I cannot output a simple string using the same Object format.

Lastly, even if I could get this to output a message, I need to be able to JSON.parse(jsonString), which I cannot due as the the jsonString is not in a valid json format.

1 Answer 1

6
<aura:attribute name="item" type="Object" default="{ name: 'Chuck'}" />

This ends up being parsed as a String, and because the thing gets wrapped up in a Proxy, JSON.parse ends up with an exception.

Instead, define it as a Map:

<aura:attribute name="item" type="Map" default="{ name: 'Chuck'}" />
<h1>{!v.item.name}</h1>

This will output the expected value.

As noted in the documentation:

We recommend using type="Map" instead of type="Object" to avoid some deserialization issues on the server. For example, when an attribute of type="Object" is serialized to the server, everything is converted to a string. Deep expressions, such as v.data.property can throw an exception when they are evaluated as a string on the server. Using type="Map" avoids these exceptions for deep expressions, and other deserialization issues.

5
  • <h1>{!item.name}</h1> throws an error. If I change the item attribute to <aura:attribute name="item" type="String" default="Chuck" />, then <h1>{!v.item}</h1> outputs Chuck. So it seems v is required. Am I missing something? Commented Feb 6, 2018 at 20:35
  • 1
    @SwisherSweet don't confuse the two: Object[] and Object are two different things. However, you shouldn't use Object for your purpose, you actually need to use Map. Give me a sec, I'll edit.
    – sfdcfox
    Commented Feb 6, 2018 at 20:52
  • 2
    @SwisherSweet -> developer.salesforce.com/docs/atlas.en-us.lightning.meta/… why you should use map insteaad
    – glls
    Commented Feb 6, 2018 at 20:54
  • @sfdcfox, i knew you did =P, wasnt sure if OP did, anyways, you linked it in your psot now =)
    – glls
    Commented Feb 6, 2018 at 20:57
  • Thanks for the help. I will use Map instead. Commented Feb 7, 2018 at 16:49

You must log in to answer this question.

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