A simple refresher. Use BehaviourSubject if you want to receive some initial / current values upon subscribing( manually in services/pipe etc, or via async pipe in html templates. Here is a basic proposal for what you are trying to achieve. Of course there is a lot more to be done considering production. Regards.
chat.service.ts:
BackEndDB : ChatMessage[] = <Obtain data for chatHistory from your DB>();
If you use any BackEnd storage for your chat history, initialize BackEndDB via that source , if not let messages$ to be new BehaviorSubject<ChatMessage[]>(null);. This will not persist your chat history if you reload the page.
messages$ = new BehaviorSubject<ChatMessage[]> // (this.BackEndDB OR null);
sendMessage(message: ChatMessage): void {
this.BackEndDB.push(message);
this.messages$.next(this.BackEndDB);
}
getMessages(): Observable<ChatMessage[]> {
return this.messages$.asObservable();
}
and then in your component:
import {ChatService} from 'yourPath/chat.service';
@Component({
selector: 'app-chat',
templateUrl: ['./chat.component.html'],
styleUrls: ['./chat.component.css'],
})
export class ChatComponent {
inbox$: Observable<ChatMessage[]>;
constructor(private chatService: ChatService) {
this.inbox$ = this.chatService.getMessages();
}
sendMessage(username, msg) {
let message: ChatMessage = {
msg: msg,
sender: username
}
this.chatService.sendMessage(message);
}
}
and then chat.component.html:
<label> Your Name: </label>
<input type="text" #userName>
<label> Your Message: </label>
<input type="text" #userMessage>
<button type="button" (click) = "sendMessage(userName.value,userMessage.value)">Send</button>
<div *ngIf="inbox$ | async; let messages ">
<div *ngFor= "let message of messages ">
<p> {{ message.sender }} </p>
<p> said: </p>
<p> {{ message.msg }} </p>
</div>
</div>
You can create the ChatMessage Interface in a shared folder, if you are going to reuse it, or directly in your component in case it is only used there:
interface ChatMessage {
msg: string;
sender: string;
}
The only reason we push the new messages to the BackEndDB variable and then call next on it, is because this is a simple demo. In reality you would use FirestoreCollectionDocument.valueChanges() or any other realtime data service.
ObservableandSubject?Observableis unicast and aSubjectis multicast. You are wrong when you saying Observables are already multicast.Subjectis both a producer and a data consumer. - Serkan Sipahi