Home > Back-end >  Angular observable updating boolean and object
Angular observable updating boolean and object

Time:01-21

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:

https://stackblitz.com/edit/angular-empty-project-qqkucy? file=app/test.service.ts,app/app.component.ts,app/app.component.html&file=app/app.component.ts

=====================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);
  }
}

  • Related