I new to RxJs and practicing. I just used simplest of angular code rather than console.log for output.
My copmonent code is:
import { Component } from '@angular/core';
import { Observable, map, of, Subject, BehaviorSubject, AsyncSubject, concat } from 'rxjs';
import { ajax } from 'rxjs/ajax';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
obs1$ = of(1, 2, 3);
obs2$ = of(4, 5, 6);
obs3$ = of(7, 8, 9);
concat$ = concat(this.obs1$, this.obs2$, this.obs3$);
}
My template code is:
<p *ngFor="let x of concat$ | async">
{{x}}
</p>
The above code is giving me the following error: Cannot find a differ supporting object '9' of type 'number'. NgFor only supports binding to Iterables, such as Arrays. Screen shot attached.
When I am subscribing and outputing in console it is giving result as expected: 1, 2, 3, till 9.
Am I missing something? Something I did not understand yet?
Please help me on this query.
Simply outputing
{{concat$ | async}}
is displaying 9 on the UI. The last emitted value.
When I am subscribing and outputing in console it is giving result as expected: 1, 2, 3, till 9.
In RxJs, concat
isn't the same the concat
you'd use on an array. Concat is to chain sequentially a list of observables. They'll still emit one value at a time.
Meaning that in your view, you wouldn't need an ngFor
, as what you get isn't an array but rather a value at one point in time.
So when you do
obs1$ = of(1, 2, 3);
obs2$ = of(4, 5, 6);
obs3$ = of(7, 8, 9);
concat$ = concat(this.obs1$, this.obs2$, this.obs3$);
You'll get one value at a time: 1, 2, 3, 4, 5, 6, 7, 8, 9
So either you just display the current value... OR you want to display all the values. For this, you have 2 options:
You want to display all the values received at once, at the end once the observable is closed. In which case you can do exactly what fuji as explained with toArray.
Otherwise, if you prefer to show accumulated values over time, essentially get:
[1]
[1, 2]
[1, 2, 3]
...[1, 2, 3, 4, 5, 6, 7, 8, 9]
You can use scan
to accumulate values over time but still emit intermediate values:
concat(this.obs1$, this.obs2$, this.obs3$).pipe(
scan((acc, curr) => [...acc, curr], [])
)