Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does first() rxjs operator keep returning array

I have a service with a function of type

getSummary(id: string, universe: string): Observable<INTsummary[]>

When I call this I only ever want the first item in the INTsummary[], so I'm trying to use rxjs first operator to do this:

  loadQuickSummary(){
    var obj = this.myService.getSummary(this.user.id, this.user.universe).first();
    console.log("getting quick summary");
    obj.subscribe(r => {
      console.log(`first value ${JSON.stringify(r)}`)
    })
  }

from reading docs and stackoverflow, this should return an object, but instead I get back an array of INTsummary's .

How can I get back just the first object in the INTsummary[] array?

like image 687
Jonathan Portorreal Avatar asked Aug 10 '17 16:08

Jonathan Portorreal


Video Answer


2 Answers

The first() return the first emission for an Observable. So when you have source that emits arrays like INTsummary[] then it takes the first array it emits (not the first item in the array).

From your description you want to get the first item in the array so there're are two ways:

this.myService.getSummary(this.user.id, this.user.universe)
  .map(array => array[0])

... or if you really want to use the first() operator:

this.myService.getSummary(this.user.id, this.user.universe)
  .concatAll() // flatten the array into separate emission
  .first()
like image 178
martin Avatar answered Sep 19 '22 23:09

martin


Right, but the object returned is an array, that what this type states:

Observable<INTsummary[]>

If it returned plain objects, you would have:

Observable<INTsummary>

You can use mergeMap operator to flatten the array:

var obj = this.myService.getSummary(this.user.id, this.user.universe).first().mergeMap(r => r);
like image 33
Max Koretskyi Avatar answered Sep 17 '22 23:09

Max Koretskyi