Actually this is interesting question and couldn't found exact question on the SO.
This is my solution, I wrote helper methods for easier understanding and future code reuse:
My solution on Live StackBlitz editor Link
import { from, timer, Observable } from 'rxjs';
import {
scan,
map,
concatMap,
share,
} from 'rxjs/operators';
const timeOf = (interval: number) => <T>(val: T) =>
timer(interval).pipe(map(x => val));
const timed = (interval: number) => <T>(source: Observable<T>) =>
source.pipe(
concatMap(timeOf(1000)),
map(x => [x]),
scan((acc, val) => [...acc, ...val]),
)
And the usage is:
arr = [1, 2, 3, 4, 5]
arr$ = from(this.arr)
.pipe(
timed(1000),
)
As for HTML will be:
<div *ngFor="let i of arr$ | async">
<b>{{ i }}</b>
</div>
As for explanation:
from(this.arr) will emit each of the array items separately and then I am using concatMap() for each emitted item to the timer(1000), which is essentialy delaying each emitted item for 1 second. Finally, I am using scan() operator to combine each emitted item back in the final accumulated array.