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);
},
1
  • 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
    Commented Jul 18, 2020 at 17:39

1 Answer 1

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.

1
  • Throws an error: ReferenceError: Action failed: c: SortingC $ controller $ sortByDescription [getValue is not defined] Commented Jul 18, 2020 at 17:04

You must log in to answer this question.

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