2

How Can i reverse without changing positions of elements in an array, should just update the view with a pipe

I can use array.reverse() but that places the first item at the last and so on so elements index changes

Here is stackblitz code which I am stuck at

    import { Component } from '@angular/core';

export interface Order {
  value: string;
  viewValue: string;
}

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

@Pipe({
  name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

  transform(value: any[], arg: string): any {
    console.log('value', value);
    console.log('args', arg);

    if (arg === 'desc') {
      return value.reverse();
    }

    if (arg === 'asc') {
      return value;
    }
  }

}

/**
 * @title Basic select
 */
@Component({
  selector: 'select-overview-example',
  template: `<h4>Basic mat-select</h4>
<mat-form-field>
    <mat-label>Sort Order</mat-label>
    <mat-select value='asc'>
        <mat-option *ngFor="let order of orders" (click)="changeOrder(order.value)" [value]="order.value">
            {{order.viewValue}}
        </mat-option>
    </mat-select>
</mat-form-field>


<ul>
    <li *ngFor="let item of items| orderBy : sort; index as i">{{i}} -> {{item}}</li>
</ul>`,
  styleUrls: ['select-overview-example.css'],
})
export class SelectOverviewExample {
  orders: Order[] = [
    { value: 'asc', viewValue: 'Ascending' },
    { value: 'desc', viewValue: 'Descending' }
  ];

  items: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  sort: string = 'asc';

  changeOrder(val: string) {

    console.log('val', val);

    this.sort = val;
  }

}
dota2pro
  • 7,220
  • 7
  • 44
  • 79
  • 1
    Possible duplicate of [angular 2 sort and filter](https://stackoverflow.com/questions/32882013/angular-2-sort-and-filter) – adamdport Jun 26 '19 at 19:29
  • Angular has a whole appendix about why they got rid of `orderby` here: https://angular.io/guide/pipes#no-filter-pipe – adamdport Jun 26 '19 at 19:31
  • @adamdport thanks for the info, edited my question – dota2pro Jun 26 '19 at 20:13
  • Could you just clone the array `let clone = yourArray.slice(0)` and use the clone for display? – adamdport Jun 26 '19 at 23:49
  • @adamdport so everytime a user clicks on sort i create a new array ? – dota2pro Jun 27 '19 at 00:39
  • 1
    Sure, or you can sort the clone as many times as you want without affecting the original array. Just an idea, I haven't needed it. It looks like [that's what Material's table does](https://github.com/angular/components/blob/master/src/material/table/table-data-source.ts#L265) – adamdport Jun 27 '19 at 13:27

3 Answers3

4

Our main problem is to change view only in reverse order. so no need to update logic. only update CSS.

If items are display using flex-box CSS, then we can reverse it by using flex-direction property.

    flex-direction : row;
    flex-direction: column;
    flex-direction: row-reverse;
    flex-direction: column-reverse;

and if items are display using UL and LI, then apply below css for reverse Order. like below :

ul {
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
ul > li {
    -moz-transform: rotate(-180deg);
    -webkit-transform: rotate(-180deg);
    transform: rotate(-180deg);
}
Mayur Kukadiya
  • 2,461
  • 1
  • 25
  • 58
0

You can make a custom pipe for sorting asc or desc and sort your array

##TEMPLATE##
<div *ngFor="let order of Orders | orderBy:'asc'">

##PIPE##
export class OrderByPipe  implements PipeTransform {
transform(orders: any[], field: string): any[] {
    orders.sort((a: any, b: any) => {
    if (a[field] < b[field]) {
     return -1;
    } else if (a[field] > b[field]) {
      return 1;
    } else {
        return 0;
    }
    });
    }
}
  • Can you please add this in stackblitz link above so that i can understand better and why do i need to create a new pipe just to do a simple sort ? – dota2pro Jun 26 '19 at 19:25
  • in angularjs, they orderby in ng-repeat is a 'pipe', but new Angular doesn't have the pipe like that: https://angular.io/guide/pipes. That's why you need to create a custom pipe, or you can just sort the array before looping. – katwhocodes Jun 26 '19 at 19:33
  • Hi @dota2pro here you are https://stackblitz.com/edit/sorting-angular-pipe?file=src/app/app.component.html – Roliver Javier Jun 26 '19 at 20:29
  • @RoliverJavier Thanks but this is same as array.reverse() it actually changes the array index if you desc 0 index now contains 10 – dota2pro Jun 26 '19 at 20:31
  • mmmm, you can't sort an array and expect its indexes to stay the same, for that i would create an array of object and then add an id property. https://stackblitz.com/edit/angular-edswgw-avsvrq – Roliver Javier Jun 26 '19 at 21:16
  • Nice thats what I was looking for I thought maybe by using a pipe it wont change the original array but i was wrong – dota2pro Jun 26 '19 at 21:22
0

You can clone your array using let clone = myArray.slice();. Reordering the clone will not impact the original array. It looks like that's what Material's table does.

adamdport
  • 11,687
  • 14
  • 69
  • 91