Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple map() calls in an Angular 6 service

I have an HTTP GET request that returns multiple objects that I want to turn into multiple observables. Here is an example of the response:

{
    lookup1: 
    [
      {
        "label": "lookup1 option 1",
        "value": 1
      },
      {
        "label": "lookup1 option 2",
        "value": 2
      }
    ],
    lookup2: 
    [
      {
        "label": "lookup2 option 1",
        "value": 1
      },
      {
        "label": "lookup2 option 2",
        "value": 2
      }
    ]
}

Here is my service that gets two observables:

this.lookup1 = this.apiService.get('/lookups/')
  .pipe(map(response => response["lookup1"]));
this.lookup2 = this.apiService.get('/lookups/')
  .pipe(map(response => response["lookup2"]));

How do I do this with one HTTP GET request?

EDIT

Note that code like this will do 2 HTTP GET requests:

let lookups = this.apiService.get('/lookups/');
this.lookup1 = lookups
  .pipe(map(response => response["lookup1"]));
this.lookup2 = lookups
  .pipe(map(response => response["lookup2"]));
like image 376
Jess Avatar asked Jul 24 '18 14:07

Jess


1 Answers

Method 1

Create 2 subjects that will be updated once the request resolves.

let map1 = new Subject();
let map2 = new Subject();

this.lookup1 = map1.pipe(map(response => response["lookup1"]));
this.lookup2 = map2.pipe(map(response => response["lookup2"]));

this.apiService.get('/lookups/').subscribe( response => { 
   map1.next(response);
   map2.next(response);
})

Method 2

You can use concatMap and from to transform a stream into another.

this.apiService.get('/lookups/').pipe(
  concatMap( responseJson => from(Object.values(responseJson)))
).subscribe( arrayElement=> console.log(arrayElement))

Output :

// first object emitted : 
[
  {
    "label": "lookup1 option 1",
    "value": 1
  },
  {
    "label": "lookup1 option 2",
    "value": 2
  }
]

// second object emitted :

[
  {
    "label": "lookup2 option 1",
    "value": 1
  },
  {
    "label": "lookup2 option 2",
    "value": 2
  }
]

concatMap takes an Observable and emits another Observable.

from transforms an iterable element into a stream. You'll get as much emissions as items in the iterable.

like image 163
madjaoue Avatar answered Sep 25 '22 13:09

madjaoue