Using first() operator on an observable to get the first element
Solution 1
When you use .map()
, its argument is the type of the Observable
.
Since the one you have in your service is an Observable<Member[]>
, then processArray
in
.map(processArray => {
return processArray.filter(x=> x.type === "member")
//.first()
})
is an array - a Member[]
.
Thus that .filter()
you are calling is Array#filter()
not Observable#filter()
.
The same way the .first()
you would be calling would be Array#first()
not Observable#first()
.
Since Array
does not have a .first()
array, it yields a runtime error (see plunker).
Going further, if you instead call .first()
at the Observable
, you wouldn't see much difference, since it is an Observable<Member[]>
, it would get the first element of that Observable
which is the whole array.
Solutions:
If you really want it to keep being an Observable<Member[]>
and retrieve just the first member, you could do (see plunker):
.map(processArray => {
console.log('pa2', typeof processArray);
return [ processArray.filter(x=> x.type === "member")[0] ] // <-- [0] to get first item
// wrap the result in [ ]s, because it expects an array
})
Though what I advise you to do is to turn the observable into an Observable<Member>
(instead of Observable<Member[]>
). You can do that using .mergeMap()/.flatMap()
.
app/member.service.ts
import 'rxjs/add/operator/mergeMap'; // <------------------ add this import
getMembers (): Observable<Member> { // <----------- changed from Member[] to Member
var one = this.http.get(this.memberUrl)
.map( this.extractData )
.mergeMap(processArray => { // <----------------- map to mergeMap
return processArray.filter(x=> x.type === "member")
}).first() // <----------------------- now you can use .first()
app/member-list.component.ts
import 'rxjs/add/operator/toArray'; // <------------------ add this import
...
getMembers() {
this.memberService.getMembers().toArray() // <-------------- add .toArray()
.subscribe(
Solution 2
I was able to access the Observable's first member by using angular's async pipe.
ypurComponent.html
(yourObservable | async | slice :0:1)
Admin
Updated on August 11, 2022Comments
-
Admin over 1 year
I am kind of new to RxJS, In this plunk I am trying to return the first member in the array, I have tried the
first()
operator but it returns nothing:var one = this.http.get(this.memberUrl) .map( this.extractData ) .map(processArray => { return processArray.filter(x=> x.type === "member") //.first() })
Whats wrong with the commented line in
app/member.service.ts
?