0

I have an observable which I use in html with async pipe and I want to sort it by label at first, but don't understand how to do it correctly inside pipe. Label could be one of this 'High', 'Medium', 'Low', and also there is always first object with empty label, I should leave it on first place as it is, so if I receive array like this:

[
  {name: 'ALWAYS FIRST', label: ''},
  {name: 'test1', label: 'High'},
  {name: 'test2', label: 'Low'},
  {name: 'test3', label: 'Medium'},
  {name: 'test4', label: 'High'}, 
  ...
]

I need to sort it like this

[
  {name: 'ALWAYS FIRST', label: ''},
  {name: 'test1', label: 'High'},
  {name: 'test4', label: 'High'}, 
  {name: 'test3', label: 'Medium'},
  {name: 'test2', label: 'Low'},
  ...
]

Here's my code

html

<div *ngIf="photos$ | async as photos">
  <div *ngFor="let photo of photos" class="photo-item">
    {{photo.name}}
  </div>
</div>

ts

photos$: Observable<Photos[]>;

ngOnInit() {
  this.photos$ = this.store.select(selectPhotos)
    .pipe(
      ?
    );
}

Would be grateful for any help!

MarkMark
  • 174
  • 1
  • 11

3 Answers3

1

You don't need pipe actually to solve that, you could operate on the array itself in the subscribe. Or in map() to transform the entire data inside the pipe() function.

Here's a quick example: https://stackblitz.com/edit/angular-ivy-dvs3j2?file=src%2Fapp%2Fapp.component.ts

akkonrad
  • 1,043
  • 1
  • 10
  • 25
1

Inside the pipe you need a map operator which maps the array to it's sorted counterpart.

this.photos$ = this.store.select(selectPhotos).pipe(
  map(photosArray => photosArray.sort(/* compareFunction */)),
);

However, I highly recommend to not do this in the component after selection from the store. From a experienced point of view I recommend to create another selector to select the photos sorted, so other components can use the very same selector without having to care about the sorting.

this.photos$ = this.store.select(selectPhotosSortedByLabel);
MoxxiManagarm
  • 8,735
  • 3
  • 14
  • 43
0
  1. Adapt the sort mechanism from https://stackoverflow.com/a/46256174/6513921.
  2. Use spread assignment to separate the first element from the rest of the array.
photos$: Observable<Photos[]>;

ngOnInit() {
  this.photos$ = this.store.select(selectPhotos).pipe(
    map(([first, ...rest]) => ([
      first,
      ...rest.sort((a, b) => a.label.localeCompare(b.label) || a.name.localeCompare(b.name))
    ]))
  );
}
ruth
  • 29,535
  • 4
  • 30
  • 57