Home > Mobile >  Sort values of Observable array of objects
Sort values of Observable array of objects

Time:02-11

My service get data from Api :


async getCommunes(){
    return await this._http.get<any[]>(this.api)
      .pipe()
      .toPromise()
      .then((response: any) => {
        this._communes$.next(response);
      })
      .catch(err => console.log(err))
  }

I call service in a component :


public communes$: Observable<any>;
constructor(private apiService: ApiService) { }

ngOnInit(): void {
   this.loadCommunes();
}

get communesFromService$(){
   return this.apiService.communes$;
}

async loadCommunes(){
  await this.apiService.getCommunes();
  this.communes$ =  this.apiService.communes$;
}

I display data in Html by calling communesFrom Service$ (get method) :


<div *ngFor="let record of (communes$ | async)?.records">{{record?.fields?.name}}</div>

My data are formated like below :


{
    "nhits": 38,
    "parameters": {
        "dataset": "communes-de-la-province-de-namur",
        "rows": 3,
        "start": 0,
        "format": "json",
        "timezone": "UTC"
    },
    "records": [
        {
            "datasetid": "communes-de-la-province-de-namur",
            "recordid": "5f50799324d15038c9708e48c6a32c907922d00a",
            "fields": {
                "nsi": "93088",
                "geo_shape": {
                    "coordinates": [
                        [
                            [
                                4.516510705656462,
                                50.31531488802985
                            ]
                        ]
                    ],
                    "type": "Polygon"
                },
                "geo_point_2d": [
                    50.26709679846407,
                    4.433557385138468
                ],
                "name": "Walcourt"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    4.433557385138468,
                    50.26709679846407
                ]
            },
            "record_timestamp": "2019-02-13T15:00:55.334000 00:00"
        },
        {
            "datasetid": "communes-de-la-province-de-namur",
            "recordid": "11fc2dbd6852c06f095e71adee7e0c1d334ccf24",
            "fields": {
                "nsi": "91054",
                "geo_shape": {
                    "coordinates": [
                        [
                            [
                                4.971517147861946,
                                50.02965137853804
                            ]
                        ]
                    ],
                    "type": "Polygon"
                },
                "geo_point_2d": [
                    49.98493619689069,
                    4.901523112944346
                ],
                "name": "Gedinne"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    4.901523112944346,
                    49.98493619689069
                ]
            },
            "record_timestamp": "2019-02-13T15:00:55.334000 00:00"
        },
        {
            "datasetid": "communes-de-la-province-de-namur",
            "recordid": "82a588f6f7d3250b78564fd7a1f16c0a02d0e30a",
            "fields": {
                "nsi": "92045",
                "geo_shape": {
                    "coordinates": [
                        [
                            [
                                4.827793680052161,
                                50.41154443216362
                            ]
                        ]
                    ],
                    "type": "Polygon"
                },
                "geo_point_2d": [
                    50.435523543496686,
                    4.754395027090274
                ],
                "name": "Floreffe"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    4.754395027090274,
                    50.435523543496686
                ]
            },
            "record_timestamp": "2019-02-13T15:00:55.334000 00:00"
        }
    ]
}

I only need 'name' field but order by ascending ('records' array).

I have tried this but it doesn't work. I also tried other solution but without success.:


get communesFromService$(){
    return this.apiService.communes$.pipe(
      map((response => response.sort((a,b) => a.name - b.name)))
    );
  }

How can I do that?

any suggestions is helpfull.

Thanks

CodePudding user response:

JavaScript arrays have a sort( ) method that sorts the array items into alphabetical order.

You can only get the name property out of all the values and sort it and then return it from service. Like below:-

Service Method:-

getNames(): Observable<string[]> {
    return this.http.get(`API url`).pipe(
      map((x:any) => x.records.map((item) => item.fields.name).sort())
    );
}

Component: Just assign the method to an observable:-

export class AppComponent {
  name$ = this.dataService.getNames();
  constructor(private dataService: DataService) {}
}

In Component, template use the async pipe:-

<div *ngIf="(name$ | async) as result">
  <ul>
    <li *ngFor="let item of result">{{item}}</li>
  </ul>
</div>

Demo with sample data:- https://codesandbox.io/s/optimistic-tdd-dm898?file=/src/app/app.component.html

Update :- if you have non-English alphabets in your string consider the below method for sorting.

 getNames(): Observable<string[]> {
    return of(APIReponse).pipe(
      map((x) => x.records.map((item) => item.fields.name).sort((a, b) => {
        return a.localeCompare(b, 'en', { sensitivity: 'base' });
      }))
    );
  }

CodePudding user response:

You can use just-sort-by - which is a very light library.

npm install just-sort-by

If your array is what is returned from the API call, then:

import sortBy from 'just-sort-by';

get communesFromService$(){
    return this.apiService.communes$.pipe(
      map((response) => sortBy(response, (item) => item.fields.name))
    );
}
  • Related