curtybear
curtybear

Reputation: 1538

Angular sort by json property with Angular Material md-select

Not sure how to sort a list of returned json data with a md-select. Do I need a pipe? Or just a function in my component?

Returned json object

[ { name: 'repo-name', created_at: '2017-1-15T10:30:37Z', updated_at: '2017-1-16T11:30:30Z'}, {...} ]

repos.component.html

<!-- select with function if needed -->
<md-select placeholder="Sort by">
    <md-option *ngFor="let sort of sorts" [value]="sort.value"
      (click)="sortRepos( sort.value )">
      {{ sort.viewValue }}
    </md-option>
</md-select>

<!-- repeater -->
<md-list-item *ngFor="let repo of repos ">...</md-list-item>

repos.component.ts

export class ReposComponent implements OnInit, OnChanges  {
    repos: any[] = []; // populated via API call
    errorMessage: string;
    sorts: any[] = []; // for select options in constructor
    sortBy = 'created_at'; // set default sortBy

    constructor(private _repoService: ReposService ) {
        this.sorts = [
            { viewValue: 'newest', value: 'created_at' },
            { viewValue: 'updated', value: 'updated_at' },
            { viewValue: 'alphabetical', value: 'name' },
        ];
    }

    sortRepos( value ) {
        // ??? fails, doesn't seem like the right approach
        this.sortBy = value;
        this.sortBy === 'name' ? this.repos.sort( repo => repo.name )
        : this.sortBy === 'created_at' ? this.repos.sort( repo => repo.created_at )
        : this.repos.sort( repo => repo.updated_at );
    }

    ngOnInit() {
        this._repoService.getRepos()
           .subscribe( repos => { this.repos = repos; 
           console.log(repos); },error => this.errorMessage = <any>error );
    }

    ngOnChanges() {}
}

Am I on the right track here? Or do I need a pipe that somehow gets into the .name, .created_at, and .updated_at and sorts according to that?

Thanks!

Upvotes: 0

Views: 510

Answers (1)

Lazar Ljubenović
Lazar Ljubenović

Reputation: 19764

You can create a custom pipe or just write the logic in your component. Use the Array#sort function from JavaScript. There is nothing special about Angular here, it is just your custom data transformation.

The sorting function accepts a comparison function which should return. 1, 0 or -1 based on the result of the comparison. The two arguments of this functions are two items of the array which are being compared.

The argument you're currently passing is suitable for sortBy function from Lodash, so you might be interested in using that instead of the vanilla solution.

Array#sort

const sortedArr = arr.sort((a, b) => a.name > b.name ? 1 : -1)

_.sortBy

const sortedArr = _.sortBy(arr, x => x.name)

Upvotes: 2

Related Questions