4

How to iterate over SObject list returned from server side controller in Lightning Component using <aura:iteration> to show the field values in table using dot notation.I am asking for passing field names dynamically with dot notation.

Some are marking it as duplicate, which is not. It may be possible that these guys are not getting it correctly or don't have solution to it. So please read it again to understand the problem, what I am asking. It is totally different.

Attributes I have used

<aura:attribute name="records" type="Object[]"/> **This contains sObject records**
<aura:attribute name="fieldsAPI" type="String[]"/> **Selected fields API names**
<aura:attribute name="fieldsName" type="String[]"/> **Selected fields label Names**

Here is what I have tried and done so far : My Record Area

<table class="slds-table slds-table--bordered slds-no-row-hover slds-table--cell-buffer">
                <thead>
                    <tr class="slds-text-title--caps">
                        <aura:iteration items="{!v.fieldsName}" var="fieldName">
                            <th scope="col">
                                <div class="slds-truncate" title="{!fieldName}">{!fieldName}</div>
                            </th>
                        </aura:iteration>
                    </tr>
                </thead>
                <tbody id="data">
                    <aura:iteration items="{!v.records}" var="record">
                        <tr class="slds-hint-parent">
                            <aura:iteration items="{!v.fieldsAPI}" var="fieldAPI">
                                <td>
                                    <div class="slds-truncate" title="{!fieldAPI}">{!record.fieldAPI}</div>
                                </td>
                            </aura:iteration>
                        </tr>
                    </aura:iteration>
                </tbody>
            </table>

If I replace {!record.fieldAPI} with literal like {!record.Name} it gives what I required, but I want it dynamically here, without javascript way to create it there and append where I want.

  • I am asking for dynamic sObject, not for hard coded object type. – Saran Dev Nov 23 '16 at 9:21
  • Return a map of field name to field value from server-side and iterate through that in lightning component. – Santanu Halder Nov 23 '16 at 11:10
  • @SantanuHalder can you please explain in detail with example. – Saran Dev Nov 23 '16 at 11:15
  • Do you still need it or you have got a solution? – Santanu Halder Nov 24 '16 at 11:56
  • No solution is suggested yet. @SantanuHalder – Saran Dev Nov 24 '16 at 12:07
1

This is pretty old, but figured I'd try to answer anyway for people that may still be having trouble with this.

In short, I have not found a way to accomplish exactly what you're looking for but have a workaround that works pretty well for my use cases.

Essentially, I create a child component and handle the references there. Here's a quick bare-bones example:

Parent component:

<aura:iteration items="{!v.records}" var="record">
    <tr class="slds-hint-parent">
        <aura:iteration items="{!v.fieldsAPI}" var="fieldAPI">
            <c:ChildComponent record='{!record}' fieldName='{!fieldAPI}'/>
        </aura:iteration>
    </tr>
</aura:iteration>

Child component:

<aura:attribute name='record' type='Object'/>
<aura:attribute name='fieldName' type='String'/>
<aura:attribute name='fieldValue' type='String'/>


<td>
    <div class="slds-truncate" title="{!v.fieldName}">{!v.fieldValue}</div>
</td>

Child controller (init):

var fieldName = component.get('v.fieldName');
component.set('v.fieldValue', component.getReference('v.record.' + fieldName));

This way, you can reference the object fields dynamically while still preserving the binding (e.g. if you update the field from the child, it is reflected in the parent as well through the use of getReference). Also, instead of iterating over a list of strings I typically use a wrapper class containing some additional field information to handle different field types gracefully (helpful when building dynamic forms and the like).

Sure, you have to jump through a few hoops, but this method has helped me alot with dynamic components

0

I think you can use wrapper class in controller and pass the sobject list to wrapper class.. below is sample code.

List<ContentVersion> customObjects = [Select Id,FileExtension,ContentSize,FileType,ContentDocumentId,OwnerId,Locked__c,Locked_By__c,LastModifiedDate,PathOnClient,Title from ContentVersion Where ContentDocumentId=:acctd.ContentDocumentId  and IsLatest = true ];
                List<WrapperClass> wcList = new List<WrapperClass>();
                for(ContentVersion acct : customObjects){    
                    user con = [SELECT name from user where Id=:acct.OwnerId];
                    WrapperClass wc = new WrapperClass();
                    wc.count=listAcct.size();
                    wc.uname=con.name;
                    wc.acc = acct;
                    wcList.add(wc);

and in component you can use aura: iteration and wrapperclass list , below is sample code

<aura:attribute name="accounts" type="WrapperClass[]"/>

<aura:iteration items="{!v.accounts}" var="account">

<div class="slds-truncate" title="{!account.uname}">{!account.uname}</div>  
<div class="slds-truncate" title="{!account.acc.LastModifiedDate}">{!account.acc.LastModifiedDate}</div>


</aura:iteration>

Hope it helps..

Thanks.

  • This is not relevant to my solution as I am asking to use attribute name in dot(.) notation in iteration. – Saran Dev Nov 23 '16 at 11:13
  • I don't want to use literals with dot notation, I am using dynamic field API names with dot notation which is not supported, so if any workaround please be specific with example. – Saran Dev Nov 23 '16 at 11:18
  • Can you post the code what you have tried so far, from that i can have a look and help you further..if i can...thanks. – visu Nov 23 '16 at 12:59
  • I have posted the code, I have tried @visu – Saran Dev Nov 24 '16 at 14:20
0

There is a solution worked here in this blogpost

The Idea is to use the Javascript bindings as a mechanism to achieve .You will use $A.createComponent to inject the inputtext depending on the field types

var sobjectrecord = a.getReturnValue();
 for (var idx in fieldList) {
   console.log(fieldList[idx]);
   console.log(sobjectrecord[fieldList[idx]]);
   $A.createComponent(
     ui:inputText;,
     {
      label: fieldList[idx],
       value: sobjectrecord[fieldList[idx]],
       class: outputCls;
     },
     function(newCmp){
        //Add the field list to the body array
        if (component.isValid()) {
           var body = component.get("v.body");
           body.push(newCmp);
           component.set("v.body", body);
     }
   }

The code in the above should work with little modifications .

There is also an answer here that shows how to use fieldsets you can adopt that approach as well .

  • I have already done it through javascript way, but I don't want to. I just need a way that works on component itself. – Saran Dev Nov 25 '16 at 7:44

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.