30

I try to sort the array object by date for my Angular 6 application. The data has string format. I wonder if there is an existing module to perform sort in Angular or we have to build sort function it in Typescript.

Angular Template

<app-item *ngFor="let item of someArray"></app-item>

The Array

[
  {
    CREATE_TS: "2018-08-15 17:17:30.0",
    Key1: "Val1",
    Key2: "Val2",
  },
  {
    CREATE_TS: "2018-08-15 17:25:30.0",
    Key1: "Val1",
    Key2: "Val2",
  },
  {
    CREATE_TS: "2018-08-15 17:28:30.0",
    Key1: "Val1",
    Key2: "Val2",
  }
]

9 Answers 9

37

For recent first:

this.data.sort((a, b) => new Date(b.date1).getTime() - new Date(a.date1).getTime());

For OlderFirst:

this.data.sort((b, a) => new Date(b.date1).getTime() - new Date(a.date1).getTime());
Sign up to request clarification or add additional context in comments.

2 Comments

In both cases, it should be this.data.sort((a, b)
In Angular 16, this still works
33

You can use Array.sort for sort data.

I have created a demo on Stackblitz. I hope this will help/guide to you/others.

component.ts

  data = [
    {
      CREATE_TS: "2018-08-15 17:17:30.0",
      Key1: "Val1",
      Key2: "Val2",
    },
    {
      CREATE_TS: "2018-08-15 17:25:30.0",
      Key1: "Val1",
      Key2: "Val2",
    },
    {
      CREATE_TS: "2018-08-15 17:28:30.0",
      Key1: "Val1",
      Key2: "Val2",
    }
  ]

  get sortData() {
    return this.data.sort((a, b) => {
      return <any>new Date(b.CREATE_TS) - <any>new Date(a.CREATE_TS);
    });
  }

component.html

<div *ngFor="let item of sortData">
  {{item.Key1}} -- {{item.CREATE_TS}} 
</div>

Comments

19

you can use the sort function for arrays, it takes in compare function. Parse the Date string into a date object and sort by it.

read more about here

var myArr = [


{
    CREATE_TS: "2018-08-15 17:17:30.0",
    Key1: "Val1",
    Key2: "Val2",
  },
  {
    CREATE_TS: "2018-08-15 17:25:30.0",
    Key1: "Val1",
    Key2: "Val2",
  },
  {
    CREATE_TS: "2018-08-15 17:28:30.0",
    Key1: "Val1",
    Key2: "Val2",
  }
]
myArr.sort((val)=> {return new Date(val.CREATE_TS)})

Ascending

myArr.sort((val1, val2)=> {return new Date(val1.CREATE_TS) - new 
Date(val2.CREATE_TS)})

Descending

myArr.sort((val1, val2)=> {return new Date(val2.CREATE_TS) - new 
Date(val1.CREATE_TS)})

4 Comments

Given the format that the timestamps are in, you don't actually need to convert them into a Date object. A simple string comparison (val1.CREATE_TS > val2.CREATE_TS) would suffice.
@SimonK It compiled with an error because, in the sort comparison, it can not return a boolean.
Right, I forgot it was supposed to be a number. Go with val1.CREATE_TS > val2.CREATE_TS ? 1 : -1
What if date is null or empty ? @Tiisetso
16

in addition to cryptic's answer, you will likely want to wrap the sorted values in an accessor for including in the template, adding a getter in your typescript class:

public get sortedArray(): YourItemType[] {
    return this.myArr.sort(...);
}

and in the template:

<app-item *ngFor="let item of sortedArray"></app-item>

alternately, you can sort the array as you get it into your component class and store the sorted version there, however the accessor pattern can be quite useful for dynamic sorting.

Comments

10

Using this method in Typescript, you can easily sort date values in whatever order you’d like. You can also sort any type of other data types, like number or string, by simply removing the new Date() and getTime methods.

this.data.sort((a, b) => new Date(b.CREATE_TS).getTime() - new Date(a.CREATE_TS).getTime());

Comments

5

From looking through the docs, there doesn't seem to be any built-in array sorting. However, you can do this in your template:

<app-item *ngFor="let item of someArray.sort(sortFunc)"></app-item>

And then in your component.ts file, define the function, because you cannot define functions in your template:

sortFunc (a, b) {
  return a.CREATE_TS - b.CREATE_TS
}

Edit: Simon K pointed out that the string format allows for straight comparison without coercing to Date and then to number. My original equation (for scenarios where your date string isn't that convenient):

return new Date(a.CREATE_TS).getTime() - new Date(b.CREATE_TS).getTime()

Comments

4

You should first parse the dates to miliseconds, then perform sorting, in order to avoid the "the left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type" typescript error when you return new Date(a.CREATE_TS) - new Date(b.CREATE_TS):

someArray.sort((a: any, b: any) => { return Date.parse(a.CREATE_TS) - Date.parse(b.CREATE_TS) });

Comments

3

With moment.js you can use

const newArr = myArr.sort((a, b) => moment(b.date).unix() - moment(a.date).unix());

Comments

1

For those who a researching on how to do this. I created a small type-safe array sorting method with support for deeply nested properties and Typescript autocompletion.

https://github.com/jvandenaardweg/sort-by-property

https://www.npmjs.com/package/sort-by-property

Example:

arr.sort(sortByProperty('CREATE_TS', 'asc'));

Comments

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.