[Fixed] Modify and return data from Observable : Angular

Issue

I have a service to get a list of properties, inside that service I am modifying the response using map and returning final array as Observable.

But How I can get that final array as simple JSON from service to my component. This what I have done so far.

SERVICE

getPropertyList(){
    let propertyList$ : Observable<any> = this._http.get('http://localhost:3000/...');

    return propertyList$.pipe(
      map(data => {
        // do your transformations
        let listArray: Array<any> = data.response.dataset;
        listArray.forEach(list => {
          list.name = 'jhon deo';
        })
        return listArray;
      })
    )
}

Component

this._service.getPropertyList()
 .subscribe({
   next: (result) => {
     console.log(result);
   },
   error: (err) => {
     console.log(err);
   }
})

I am trying to achieve it like this from Component –

getData(){
   const listData: Array<any> = this._service.getPropertyList();
}

Solution

Initially, when working with observables, it can feel like you want to get the data out of the observable and store it someplace else. But, usually this isn’t necessary. Most of the time, you can simply use various pipeable operators to design the behavior and data transformation of your emitted values.

You say you want this in your component:

getData() {
   const listData: Array<any> = this._service.getPropertyList();
}

But, you could just define the data as an observable that delivers the data whenever it is available instead of defining it as a method:

data$: Observable<Array<any>> = this._service.getPropertyList();

Doing it this way makes your component simpler, because the component does not need to be concerned with fetching the data, it simply references the observable, which will deliver the data any time it changes.

I like to think of the $ as a little indicator that this thing is a "value that is automatically updated" (observable).

Now, instead of subscribing in your component (previously):

this._service.getPropertyList()
 .subscribe({
   next: (result) => {
     console.log(result);
   },
   error: (err) => {
     console.log(err);
   }
})

You can simplify by defining your data$ as an observable and leveraging Angular’s async pipe to handle the subscription for you, from the template:

data$ = this._service.getPropertyList().pipe(
   tap(result => console.log(result)),
   catchError(err => console.log(err))
});
<ul>
  <li *ngFor="let item of data$ | async">{{ item.name }}</li>
</ul>

Operators Used:

  • tap – Perform any side effect logic without altering the emitted values
  • catchError – catch errors that occur in observable stream

Leave a Reply

(*) Required, Your email will not be published