Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJs how to map the items in an Observable<Array>

Tags:

angular

rxjs

I have created some simplified code to illustrate my issue.

My observable emits an array. I am trying to map the items in the array but I am forced to use Array.map within the RxJS map operator to achieve this. I am looking for a more RxJs way of achieving the same thing that does not use Array.map. Here is a stackblitz and here is the basic code. Thanks.

this.myObservable$ = of(json).pipe(
  map((data: any[]) => {
    return data.map((navigation: any) => {
      return <INavigation> {
        Id: navigation.Id,
        AppId: navigation.NavAppId,
        NavId: navigation.NavId,
        Name: navigation.NavName,
        ParentId: navigation.NavParentId,
        PageURL: navigation.NavPageURL,
        Position: navigation.NavPosition,
        Active: navigation.NavActive,
        Desktop: navigation.NavDesktop,
        Tablet: navigation.NavTablet,
        Phone: navigation.NavPhone,
        RoleId: navigation.NavRoleId,
        Target: navigation.NavTarget
      }
    })
  })
)
like image 535
danday74 Avatar asked Nov 02 '25 20:11

danday74


1 Answers

If you do not want to use the map method of Array but only RxJS operators, than you can leverage the fact that mergeMap requires, as parameter, a function which returns an ObservableInput and that an Array is an ObservableInput.

In this case what mergeMap does is to flatten the Array and emit its single items (mergeMap is also known as flatMap).

At the end, since you need an Array to be emitted by this.myObservable$ you can use the operator toArray.

The code looks like this

this.myObservable$ = of(json).pipe(
      mergeMap(data => data),
      map((navigation) => {
        return <INavigation> {
          Id: navigation.Id,
          AppId: navigation.NavAppId,
          NavId: navigation.NavId,
          Name: navigation.NavName,
          ParentId: navigation.NavParentId,
          PageURL: navigation.NavPageURL,
          Position: navigation.NavPosition,
          Active: navigation.NavActive,
          Desktop: navigation.NavDesktop,
          Tablet: navigation.NavTablet,
          Phone: navigation.NavPhone,
          RoleId: navigation.NavRoleId,
          Target: navigation.NavTarget
        }
      }),
      toArray()
    )

Honestly, your original solution with Array map method looks simpler and leaner.

like image 140
Picci Avatar answered Nov 04 '25 13:11

Picci