I have a service with two observables, one returns an array of numbers and another one a single boolean. If I try to udate the data after the subscription, pushing a new value to the array of numbres and change the boolean, the related view will display the updated numbers but the boolean remains the same.
here is the code on Stackblitz:
=====================service
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class TestService {
private myNumbers:number[]=[Math.random()]
myBoolean:boolean=false
updateData(){
this.myNumbers.push(Math.random())
this.myBoolean=!this.myBoolean
}
getNumbers(): Observable<number[]> {
return Observable.of(this.myNumbers);
}
getBoolean():Observable<boolean>{
this.myBoolean=!this.myBoolean
return Observable.of(this.myBoolean);
}
}
=================component
import { Component, OnInit } from '@angular/core';
import {TestService} from './test.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular 5';
constructor(private dataService:TestService){}
myNumbers:number[]=[];
myBoolean:boolean|undefined=undefined;
ngOnInit() {
this.dataService.getNumbers().subscribe({
next:(value)=>this.myNumbers=value
})
this.dataService.getBoolean().subscribe({
next:(val:boolean)=>this.myBoolean=val
})
}
subscribe_bool(){
this.dataService.getBoolean().subscribe({
next:(val)=>this.myBoolean=val
})
}
update_data(){
this.dataService.updateData();
}
}
=============view
<br>
<button (click)="update_data()">Update data</button>
Push data in array and change boolean in service (does not update the boolean in the view )
<br>
<br>
<button (click)="subscribe_bool()">new subscribe boolean</button> new subscribe (change the view)
<hr>
<hr>
<div *ngFor="let n of myNumbers;let i=index">
item {{i}}: {{n}}
</div>
boolean data: {{myBoolean}}
I can't understand why the array of numbers is updated in the view but not the boolean. If I make a new subscription the boolean value is updated. Is it something related with stream? Thanks!
CodePudding user response:
One issue is that you're using of
in your service. of
closes the stream after it's done, emitting the values you give it as an argument. From the RxJS docs: Emit variable amount of values in a sequence and then emits a complete notification.
I am also confused by the use of next
in your component. Here is a working version that updates both observables every time. I am using BehaviorSubject
so that there is an initial value when the component subscribes to the observables.
Conponent:
constructor(private dataService: TestService) {}
myNumbers: number[] = [];
myBoolean: boolean | undefined = undefined;
ngOnInit() {
this.dataService.myBoolean$.subscribe((val) => {
this.myBoolean = val;
});
this.dataService.myNumbers$.subscribe((val) => {
this.myNumbers = val;
});
}
update_data() {
this.dataService.updateData();
}
}
In the service:
@Injectable()
export class TestService {
private myNumbers: number[] = [Math.random()];
myBoolean: boolean = false;
myBoolean$ = new BehaviorSubject<boolean>(this.myBoolean);
myNumbers$ = new BehaviorSubject<number[]>(this.myNumbers);
updateData() {
this.myNumbers.push(Math.random());
this.myBoolean = !this.myBoolean;
this.myBoolean$.next(this.myBoolean);
this.myNumbers$.next(this.myNumbers);
}
}