0

Sorting fields directly from an object works, but how to sort fields from a related object? How do you access the Description__c field so that you can sort the records?

Controller

@AuraEnabled
public static List<MonthlyExpense__c> getExpenseCard(){

    
    List<MonthlyExpense__c> card = [Select Id, Name, MonthDate__c,
           (Select Name, Amount__c,  CardDate__c, Description__c FROM Expense_Cards__r)
                                  FROM MonthlyExpense__c ];
    return card;
}

Sorting.app

<aura:application controller="Login">

<aura:attribute type="List" name="data" />
<aura:attribute type="List" name="sorte" />
<aura:attribute type="Boolean" name="sortAsc" />
<aura:attribute type="String" name="sortField" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

<table>
    <thead>
        <td onclick="{!c.sortByName}">Name</td>
        <td onclick="{!c.sortByDate}">MonthDate</td>
        <td onclick="{!c.sortByDescription}">Description</td>
        
    </thead>
    <tbody>
        <aura:iteration items="{!v.data}" var="record">
            <tr>
                <td>{!record.Name}</td>
                <td>{!record.MonthDate__c}</td>
                
                <aura:iteration items="{!record.Expense_Cards__r}" 
                                var="con">
                    
                    <td>{!con.Description__c}</td>
                    
                </aura:iteration>
            </tr>
        </aura:iteration>
    </tbody>
</table>

SortingController.js

doInit: function(component, event, helper) {
    var load = component.get("c.getExpenseCard");
    load.setCallback(this, function(result) {
        component.set("v.data", result.getReturnValue());
        component.set("v.sortAsc", true);
      
    });
    $A.enqueueAction(load);
},
sortByName: function(component, event, helper) {
    helper.sortBy(component, "Name");
},
sortByAmount: function(component, event, helper) {
    helper.sortBy(component, "MonthDate__c");
},
    sortByDescription: function(component, event, helper) {
    helper.sortBy(component, "Description__c");
}

SortingHelper.js

 sortBy: function(component, field) {
    var sortAsc = component.get("v.sortAsc"),
        sortField = component.get("v.sortField"),
        records = component.get("v.data");
    sortAsc = field == sortField? !sortAsc: true;
    records.sort(function(a,b){
        var t1 = a[field] == b[field],
            t2 = a[field] > b[field];
        return t1? 0: (sortAsc?-1:1)*(t2?-1:1);
    });
    component.set("v.sortAsc", sortAsc);
    component.set("v.sortField", field);
    component.set("v.data", records);
},
  • I edited the code to address this issue. I can't at-mention you because apparently your username includes content that can't be in a comment. – sfdcfox Jul 18 at 17:39
1

You just need a helper method:

function getValue(source, target) {
  let path = target.split(/\./);
  while(path.length > 1 && source) {
    if(source instanceof Array) {
      source = source[0];
    }
    source = source && source[path.shift()];
  }
  return source && source[path[0]];
}

Then, you can plug that in to the function:

    var v1 = this.getValue(a,field),
        v2 = this.getValue(b,field),
        t1 = v1 == v2,
        t2 = v1 > v2;

And specify the entire field path in the method parameter:

helper.sortBy(component, "Expense_Cards__r.Description__c");

This function will only follow the first child of an array when using child records, but it should handle child and parent relationships in any arbitrary order.

| improve this answer | |
  • Throws an error: ReferenceError: Action failed: c: SortingC $ controller $ sortByDescription [getValue is not defined] – Алёна Опарина Jul 18 at 17:04

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.