I am trying to use the async pipe with an observable in my receiving component so that I don't need to use OnDestroy (b/c the async pipe automatically subscribes and unsubscribes for me)
In order to do this I need to change/cast/"push" an Observable<String>
to an Observable<String[]>
.
Here is the original implementation, which works fine (note I haven't implemented the OnDestroy method yet)
imports...
@Component({
selector: 'app-console-container',
template: `
<p>Console</p>
<p *ngFor="let message of msgsArr" >{{message}}</p>
`
})
export class ConsoleContainerComponent implements OnInit{
public msgsArr: string[] = [];
constructor(private msgsvc: MessageService){}
ngOnInit(): void {
this.msgsvc.getMsg() //get initial msg
this.msgsvc.getMsg().subscribe({next: msg => {this.msgsArr.push(msg)}})
}
}
So I've got the class member declaration and the template modified:
imports...
@Component({
selector: 'app-console-container',
template: `
<p>Console</p>
<p *ngFor="let message of messages$ | async" >{{message}}</p>
`,
})
export class ConsoleContainerComponent implements OnInit{
public messages$: Observable<string[]> = new Observable<string[]>();
constructor(private msgsvc: MessageService){}
ngOnInit(): void {
//need to do the cast/type conversion/"push" here
//or add another method to the service such as getMsgs which returns Observable<string[]>
}
}
but I still need to figure out how to do the cast/type conversion/"push".
I suppose it doesn't technically matter whether I do this:
ngOnInit
ORgetMsgs(): Observable<string[]>
<- probably the more correct way (separation of concerns)FYI - Here is my MessageService:
imports...
@Injectable({
providedIn: 'root'
})
export class MessageService{
private moveEmitter$ = new BehaviorSubject<string>('Start Game')
public pushMsg(msg: string ): void {
console.log('svc pushMsg ->', msg)
this.moveEmitter$.next(msg)
}
public getMsg(): Observable<string> {
console.log('svc getMsg -> ', this.moveEmitter$)
return this.moveEmitter$;
}
You can use scan
rxjs operator to perform the accumulation for the messages.
import { scan } from 'rxjs';
this.messages$ = this.msgsvc
.getMsg()
.pipe(scan((acc: string[], x: string) => [...acc, x], []));