+ Start a Discussion
FinnArildFluidoFinnArildFluido 

Passing and Accessing SObjects from lightning controller

I have a tricky little problem. I nest a couple of components, and in the top level component I am getting an SObject with a controller which works fine:
<aura:component >
	<aura:attribute name="sob" type="MySobject__c"/>
	<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
	<h3>Checking ID: {!v.sob.Id}</h3>
	<c:mySubComponent sob="{!v.sob}"/>
</aura:component>

My sub component looks like this, and also shows the Id fine (and the Name for that matter - however I have noticed here that the capitalization of those variables actually matter - but that is another kettle of fish):

<aura:component >
	<aura:attribute name="sob" type="MySobject__c"/>
	 <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
	<h3> check out the ID shows: {!v.sob.Id}</
</aura:component>

But however, in the handler - if I try to access the same variable I can access (both before and after the handler declaration) in the controller, I get null - both if I access the sobject directly, or a value on it (which is what I want to accomplish)
 
({
	doInit : function(component, event, helper) {
		console.log('### this (and all variants of it) returns null: ' + component.get('v.sob.Id');
	}
})

If I pass a String, it shows fine - but passing a sObject only seems to display values in the component and not it's controller. Anyone?
Best Answer chosen by FinnArildFluido
FinnArildFluidoFinnArildFluido
So the fix finally, was to use the RecordID as the only parameter I passed down to the components. Then I used that variable to get the sObjects I needed on each component. In my apex controller I set up all the sOjects I was getting with variables with getters so I could reduce the number of queries without having to worry about order like this: 
 
static myId;
static MySobject__c mos {
    get {
        if (mos == null) {
            mos = [select Id, Name from MySobject__c where relatedId__c = :myId];
        }
        return mos;
    }
    set;
}

@AuraEnabled
public static MySobject__c mos(Id recId) {
    myId = recId;
    return mos;
}

This is a strategy I used a lot in Visualforce pages as well - and it turns out it is gonna work good for Lightning too.

All Answers

Pramodh KumarPramodh Kumar
Hi,

Please add a default value to the attribute. Here in your scenario, it was representing as the null object.

Here is my scenario please find the code.
<aura:attribute name="selectedRecord" type="object" default="{}" description="Use,for store SELECTED sObject Record"/>

Thanks
Pramodh
FinnArildFluidoFinnArildFluido
Thanks for answering, Pramodh - unfortunately, setting default="{}" had absolutely no effect at all. The nested component still returns a nullvalue from the passed object. 
FinnArildFluidoFinnArildFluido
I have actually managed to figure out that the problem is an order-of-execution issue. Seems the javascript in the controller is called in some weird order. When I placed debug points in my code I found out that the query happened way after trying to access other variables I needed. Not sure how to fix this yet, though ...
 
FinnArildFluidoFinnArildFluido
So the fix finally, was to use the RecordID as the only parameter I passed down to the components. Then I used that variable to get the sObjects I needed on each component. In my apex controller I set up all the sOjects I was getting with variables with getters so I could reduce the number of queries without having to worry about order like this: 
 
static myId;
static MySobject__c mos {
    get {
        if (mos == null) {
            mos = [select Id, Name from MySobject__c where relatedId__c = :myId];
        }
        return mos;
    }
    set;
}

@AuraEnabled
public static MySobject__c mos(Id recId) {
    myId = recId;
    return mos;
}

This is a strategy I used a lot in Visualforce pages as well - and it turns out it is gonna work good for Lightning too.
This was selected as the best answer