1

There are similar questions but none of the answers have done the trick for me, so I would appreciate if you don't mark this as duplicate (unless you refer me to answer question that does solve the issue)

I have a Array of Objects result:Array<Object>=[]; which is returned with these values: Array Object data

On my template, I would like to sort the response based on count of 'likes'

<tr class *ngFor="let media of (result) | orderBy: 'data.likes.count'">
   <td>
     <img src={{media.data.images.standard_resolution.url}} height="100" width="100">
     <p> {{media.data.likes.count}} </p>
  </td>
</tr>

The sort pipe looks like this:

import {Pipe, PipeTransform} from '@angular/core';

@Pipe({name: 'orderBy', pure: false})

export class SortPipe {

  transform(array: Array<Object>, args: string): Array<Object> {

    console.log("calling pipe");

    if (array == null) {
      return null;
    }

    array.sort((a: any, b: any) => {
        if (a[args] < b[args] ){
        //a is the Object and args is the orderBy condition (data.likes.count in this case)
            return -1;
        }else if( a[args] > b[args] ){
            return 1;
        }else{
            return 0;
        }
    });
    return array;
  }
}

When I run this code, it shows me an unordered response, rather then sorting it based on the likes. I should point that that when I do console.log(a[args]) on the pipe I get undefined so I am probably not reading the value in the object field correctly.

3
  • does the response look like; 1,10,11,12,13,14,15,16,17,18,19,2 etc.? Just because you didnt find a solution to your specific question, doesn't mean the other answers are wrong? Commented Dec 29, 2016 at 14:22
  • Sorry, that's not what I meant. I just meant that perhaps they weren't solving the issue I am facing. To answer your question, the response is unaffected by orderBy pipe Commented Dec 29, 2016 at 14:27
  • SO isn't here to solve your specific problem, even if it's related to others that might not work for you. But anyways, I'm too drunk to care currently Commented Dec 29, 2016 at 14:33

1 Answer 1

4

You can't pass args like that

Should be :

array.sort((a: any, b: any) => {
        if (a.data.likes[args] < b.data.likes[args] ){
        //a is the Object and args is the orderBy condition (data.likes.count in this case)
            return -1;
        }else if( a.data.likes[args] > b.data.likes[args] ){
            return 1;
        }else{
            return 0;
        }
    });

And then in your template :

<tr class *ngFor="let media of (result) | orderBy: 'count'">

And if you really want to do what you're doing ( I really discourage ) , you need to use a helper to parse your data.likes.count and return the deeper object.

function goDeep(obj, desc) {
    var arr = desc.split(".");
    while(arr.length && (obj = obj[arr.shift()]));
    return obj;
}

Then you can use it like

array.sort((a: any, b: any) => {
            let aDeep = goDeep(a,args);
            let bDeep = goDeep(b,args);
            if (aDeep < bDeep ){
            //a is the Object and args is the orderBy condition (data.likes.count in this case)
                return -1;
            }else if( aDeep > bDeep ){
                return 1;
            }else{
                return 0;
            }
        });

And then you can use it like you wanted ;

<tr class *ngFor="let media of (result) | orderBy: 'data.likes.count'">
Sign up to request clarification or add additional context in comments.

2 Comments

That works! But does that mean that I need to build a separate pipe for every such sorting. I need to implement other views for the same Object so wondering if there is a way to combine ?
I see - your second way actually answers my followup question. Why do you discourage that though? Performance issues?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.