Tbit
Tbit

Reputation: 13

Angular Map and mergeMap rxjs6 operators

Newbie question:

I am trying to export my data from a rest API to firebase.

I am using Angular6 with RxJS 6.

getByTag(tag:string) {
  return this.http.get(this.URL + '/get/listings/', { headers })
    .pipe(
      map((res: Listings) => res.items),
      // How do I add an additional property to each of these items? eg res.items.inserted = new Date();
      // How do chain each of these res.items to another function called exportToFirebase(res.item))
    );
}

My Data looks something like this: https://pasteboard.co/HWp1hUb.jpg

I tried the map function but my incoming data stream from the API is an array of arrays so I attempted mergeMap without any success (https://www.learnrxjs.io/operators/transformation/mergemap.html)

I attempted a do() statement to trigger the exportToFirebase(res.item), but It looks like I am completely off track here :-P

Expected result: Create a loop to send item parameter of type Listing to my service function called exportToFirebase(res.item)

Questions?

  1. How do I add an additional property to each of these items? eg res.items.inserted = new Date(); ?

  2. How do chain each of these res.items to another function called exportToFirebase(res.item)) ?

Upvotes: 1

Views: 624

Answers (2)

8ytan
8ytan

Reputation: 347

If I've understood your question right and you want to add a field to each item in the results array then pass each one individually to the exportToFirebase() function, then something like this could be of use:

getByTag(tag:string) {
  return this.http.get(this.URL + '/get/listings/', { headers })
    .pipe(
      map((res: Listings) => res.items)
    )
    .subscribe(items => {
      items.forEach(i => {
        i.inserted = new Date();

        exportToFirebase(i);
      });
    });
}

You can also use the tap operator, as another answer mentioned, if you don't want to use subscribe.

Upvotes: 0

Danylo Gudz
Danylo Gudz

Reputation: 2656

mergeMap is useless in your case because it was created for flattening observables.

So map operator should do all the job.

getByTag(tag:string) {
  return this.http.get(this.URL + '/get/listings/', { headers })
    .pipe(
      map((res: Listings) => res.items),
      map((list: any[]) => {
        return list.map(sublist => sublist.map(item => {...item, inserted: new Date()}));
      })
    );
}

Update

You can flatten your array using reduce:

map((res: Listings) => res.items.reduce(((arr, list) => arr.concat(list), [])),

map((list: any[]) => {
  return list.map(item => {...item, inserted: new Date()});
})

To chain you can use do/tap:

tap((list: any[]) => {
  list.forEach(item => {
    exportToFirebase(item)
  });
})

So the actual execution of exportToFirebase is on your side, Idk what the signature of that function if it returns Observable or smth

Upvotes: 1

Related Questions