[SalesForce] Display data into a lightning component

I have 2 lightning components, one that display a list of articles, and the other display the details of one article. My problem is that in the second component I can't see the data, but there is no errors when I display the component.

Here is a bit of the component with the list:

<aura:attribute name="recordId" type="Id" />

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:attribute name="wrappers" type="ListeArticlesWrapper" />
<aura:attribute name="articles" type="Article__c" />

<aura:attribute name="Detail" type="String"/>
<aura:registerEvent name="navigate" type="c:NavigateToDetail"/>

<div class="page">
    <h1>Liste des articles</h1>
    <div class="slds">
        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
            <thead>
                <tr class="slds-text-heading--label">
                    <th scope="col" class="head"></th>
                    <th scope="col" class="head">Nom</th>
                    <th scope="col" class="head">Type</th>
                    <th scope="col" class="head">Prix</th>
                    <th scope="col" class="head"></th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.wrappers}" var="wrap">
                    <tr>
                        <td class="cell">
                            <ui:inputCheckbox value="{!wrap.selected}" />
                        </td>
                        <td class="cell">
                           <ui:outputText value="{!wrap.art.Name}" />
                        </td>
                        <td class="cell">
                            <ui:outputText value="{!wrap.art.Type__c}" />
                        </td>
                        <td class="cell">
                            <ui:outputText value="{!wrap.art.Prix__c}" />
                        </td>
                        <td class="cell">
                            <button class="slds-button slds-button--neutral slds-not-selected" 
                                    onclick="{!c.getDetail}" data-recId="{!wrap.art.Id}">Details</button>
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>

So it is the buttons that redirects to the other component.

Here is the controller js of the first component :

doInit : function(component, event, helper) {
    helper.init(component, event);
},

getArticles : function(component, event, helper) {
    helper.getArticles(component, event);
},

getDetail : function(component, event, helper){
    var id = event.target.getAttribute("data-recId");

    var article = component.get("v.article");

    var evt = $A.get("e.c:NavigateToDetail");
    evt.setParams({
        "detail": article
    });
    evt.fire();
}

Then the second component, which should display the detail of an article :

<aura:attribute name="items" type="Article__c[]"/>

<aura:handler event="c:NavigateToDetail" action="{!c.handleAfficherDetail}"/>

<div class="slds">
        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
            <thead>
                <tr class="slds-text-heading--label">
                    <th class="head">Name</th>
                    <th class="head">Type</th>
                    <th class="head">Prix</th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.items}" var="item">
                    <tr>
                        <td class="cell">
                            <ui:outputText value="{!item.Name}" />
                        </td>
                        <td class="cell">
                            <ui:outputText value="{!item.Type__c}" />
                        </td>
                        <td class="cell">
                            <ui:outputText value="{!item.Prix__c}" />
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
    </div>

And its controller js :

handleAfficherDetail: function(component, event, helper) {

    var product = event.getParam("detail");

    var items = component.get("v.items");
    if (!items) items = []; 
    items.push(product);
    component.set("v.items", items);
}

So when I click a button in the first component, I only can see the header of the table, but not the datas.

I case you wonder, I display the all my components in another component like that :

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:handler event="c:NavigateToDetail" action="{!c.NavigateComponent}"/>
{!v.body}

And its controller :

doInit : function(component, event, helper) {
    $A.createComponent(
        "c:ListeArticles",
        {

        },
        function(newCmp){
            if (component.isValid()) {
                component.set("v.body", newCmp);
            }
        }
    );
},

NavigateComponent : function(component,event,helper) {
    $A.createComponent(
        "c:DetailArticle",
        {
            "detailArt" : event.getParam("detail")
        },
        function(newCmp){
            if (component.isValid()) {
                component.set("v.body", newCmp);
            }
        }
    );
}

EDIT
It seems that it doesn't pass into the second component's controller, because when I put a console.log into it I can't see it … So it doesn't pass in the function handleAfficherDetail. Do you have any idea why ?

Best Answer

I think a better approach to handle that would be as parent/child components:

On the List component include the details/child component:

<c:DetailArticle aura:id="detailArticle" />

Then add an aura:method on the details/child component - instead of the event:

<aura:method name="openArticle" action="{!c.openArticle}" access="PUBLIC"> 
    <aura:attribute name="articleId" type="String" />
</aura:method>

Now handle that method from your details/child component's controller:

openArticle : function(cmp, event) {
    var params = event.getParam('arguments');
    if (params) {
        var atrId = params.articleId;
        console.log("article id: " + atrId);
        // add the article to the details page
    }
}

Now on your parent list component controller, when you want to open the article detail page from your button list controller - fire the apexMethod event like that:

getDetail : function(component, event, helper){

    // 1. get the details component
    var details = component.find("DetailArticle")

    // 2. get the article id
    var articleId = event.target.getAttribute("data-recId");

    // 3. run the child component init (aura:method)
    details.openArticle(articleId);
}
Related Topic