shakedk
shakedk

Reputation: 71

RXJS: new variable value isn't being sent by observable

I'm very new to RxJs and i'm trying to create a simple Observable that send the new variable value to the component.

Not sure what i'm doing wrong, i guess the Observable does not recognize that the variable is being changed but would love some explanation...

my component:

export class NamesListComponent implements OnInit {

  constructor(private dataService: DataService) { }

  public numArr: number[] = [];
  subscription: Subscription 

  ngOnInit(): void {

   this.subscription = this.dataService.getNum.subscribe((value: number) => {
       this.numArr.push(value);
    })
  }
  
  ngOnDestroy(): void {
    this.subscription.unsubscribe()
  }
}

my service:

export class DataService {


  private privateNum: number = 0;

  getNum = new Observable(subscriber => {
    setInterval(() => {
      this.privateNum++
    }, 1000);

    subscriber.next(this.privateNum)
  })

  constructor() {
  }
}

Upvotes: 0

Views: 228

Answers (2)

Askirkela
Askirkela

Reputation: 1209

The problem lies with the fact that angular's change detection works on references. Since you just push a value in your array, the reference does not change and the change detection does not run.

Try using the following snippet:

export class NamesListComponent implements OnInit {

  constructor(private dataService: DataService) { }

  public numArr: number[] = [];
  subscription: Subscription 

  ngOnInit(): void {

   this.subscription = this.dataService.getNum.subscribe((value: number) => {
       this.numArr = [...this.numArr, value]; // Using the spread operator, this create a new array (a new reference) and triggers change detection
    })
  }
  
  ngOnDestroy(): void {
    this.subscription.unsubscribe()
  }
}

I assume you display your array with an *ngFor in the template, if that's the case, you could also check Angular ngForOf doc, especially the trackBy function.

Upvotes: 0

Javier Martínez
Javier Martínez

Reputation: 356

You should try using BehaviorSubject or ReplaySubject.

Also, I think next() should be inside the setInterval():

getNum = new Observable(subscriber => {
    setInterval(() => {
      this.privateNum++;
      subscriber.next(this.privateNum)
    }, 1000);
  })

Upvotes: 1

Related Questions