Ian Vink
Ian Vink

Reputation: 68820

Angular async pipe with mergeMap

I am experimenting.

In my component I call an API 9 times and each time extract the title with a mergeMap. I then try to display those titles in my template, but it fails saying ngFor doesn't support string, only arrays.

titles$: Observable<string[]>;

ngOnInit(): void {
  this.titles$ = of(1, 2, 3, 4, 5, 6, 7, 8, 9).pipe(
    mergeMap<number, any>((x) => ajax.getJSON(this.apiUrl + x)),
    mergeMap<Person, any>((person) => of(person?.title ?? "bad"))
  ) as Observable<string[]>;  
}

//This nicely prints out the titles 
this.titles$.subscribe((title) => console.log(title));


<div *ngIf="titles$">
   <div *ngFor="let title of titles$ | async">
     {{ title }}
   </div>
</div>

Upvotes: 0

Views: 1680

Answers (2)

Aakash Garg
Aakash Garg

Reputation: 10979

Change your title statement to :-

this.titles$ = forkJoin(of(1, 2, 3, 4, 5, 6, 7, 8, 9).pipe(
    mergeMap<number, any>((x) => ajax.getJSON(this.apiUrl + x)).pipe(map<Person, any>((person) => person?.title ?? "bad"))
  ))

Upvotes: 0

penleychan
penleychan

Reputation: 5470

Seems like your observables return back as a string for each items, what you could do is use the toArray() operator.

this.titles$ = of(1, 2, 3, 4, 5, 6, 7, 8, 9).pipe(
    mergeMap<number, any>((x) => ajax.getJSON(this.apiUrl + x)),
    mergeMap<Person, any>((person) => of(person?.title ?? "bad")),
    toArray()
) as Observable<string[]>;  

StackBlitz: https://stackblitz.com/edit/angular-ivy-vcprxo

Upvotes: 1

Related Questions