danday74
danday74

Reputation: 57215

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

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
      }
    })
  })
)

Upvotes: 4

Views: 8320

Answers (2)

Picci
Picci

Reputation: 17762

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.

Upvotes: 6

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9774

RxJS internally uses Javascript Function only, every operator is a javascript function and you can create custom RxJS operator using JS Function.let say you are using map operator, Which will receive the observable as input, perform conversion and return an observable.

You can use Javascript map operator, which is good one. Not seeing any Rxjs operator specific for forEach.

Upvotes: 1

Related Questions