I have a very strange behavior while working with Angular 9 and Rxjs Observables. I have a component and a service. The service has a public $messages
Behavior subject, that I subscribe to in the component.
My problem is whenever I execute the next
function on the behavior subject in the chat service, the async
operator in the html seems to ignore all the operators in the pipe in the component, including the DelayWhen
operator. Although the map
operator follows the right behahvior, and executes after seconds.
What might be the cause of this behavior and how to fix it?
Chat Service
export class ChatService {
messages: Message[];
messages$: BehaviorSubject<Message[]>;
constructor(){
this.messages = [
{
message: 'Hi How can I help you today?',
created_at: '2020-04-11 17:58:27',
agent_id: '1'
},
{
message: 'Whats the pricing model?',
created_at: '2020-04-11 13:58:27',
visitor_id: '043-reer-reer-reer-re-er'
}
];
this.messages$ = new BehaviorSubject<Message[]>(this.messages);
this.cn.on("messageReceived", (message:Message) => {
this.apiService.getMessage(message.id).subscribe(
res => {
this.messages.push(res.model);
this.flush_to_storage();
this.messages$.next(this.messages); <-- I call the next here
....
}
Component
export class ChatComponent implements OnInit {
messages$: Observable<Message[]> ;
show_typing_indicator: boolean = false;
...
ngOninit(){
this.messages$ = this.chatService.messages$.pipe(
delayWhen( ms => { /* This is ignore altogether by the async in the html component */
let m = ms[ms.length - 1];
if (m.is_bot) {
this.show_typing_indicator = true;
setTimeout( () => this.show_typing_indicator = false, 3000 );
return interval(3000);
}
else return of(undefined);
}),
map( ms => {console.log(ms); return ms})
);
}
Component Html
<div class="cl-message-block" *ngFor="let m of (messages$ | async)" [@fadeIn] [class.sent]="!m.agent_id">
<div class="cl-message" [ngClass]="{ 'cl-received': (m.agent_id), 'cl-sent': (!m.agent_id) }">
{{ m.message}}
<span>{{ m.created_at | messageTime }}</span>
</div>
</div>
<charla-typing-indicator *ngIf="show_typing_indicator"></charla-typing-indicator>
map( ms => {console.log(ms); return ms})
? – Picci