I am working on chat application where i need to display bot messages one-by-one with some delay between them, such that it gives an impression that bot is typing instead of throwing all message together. I was trying this behaviour with RxJS but could not achieve the desired output.

[Stackblitz Link](https://stackblitz.com/edit/angular-ivy-fejxom?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.service.ts)

```
query(): Observable<IChatResponse> {
    const response = {
      messages: [
        {
          text: 'Please give a valid domain name',
        },
        {
          text: 'What domain do you want?',
        },
        {
          text: 'Some other messages...',
        },
      ],
    };

    return of(response).pipe(
      switchMap((response: any) => this.convertToStream(response))
    );
  }

  convertToStream(data: any): Observable<IChatResponse> {
    let count = 0;
    const messageDelayFn = (sme, idx): Observable<any> => {
      const loaderStart$ = of(null).pipe(
        tap((_) => console.log('idx ', idx)),
        delay(500 * idx),
        tap((_) => {
          this.loading$.next(true);
        })
      );
      const loaderStop$ = of(null).pipe(
        delay(1000 * idx),
        tap((_) => {
          this.loading$.next(false);
        })
      );

      const message$ = of(sme);
      return concat(loaderStart$, loaderStop$, message$).pipe(share());
    };

    const transformedObservable = of(data).pipe(
      map((chat) => {
        return {
          ...chat,
          messages: chat.messages.reduce((acc: Observable<any>[], message) => {
            return [...acc, messageDelayFn(message, ++count)];
          }, []),
        };
      })
    );

    return transformedObservable;
  }

```

Behaviour i am expecting is something like this --,

* starts with loader for 500ms
* loader stops
* emits first message
* again loader starts for 500ms (before emitting second message)
* loader stops
* emits second message
* ...and so on