Reputation: 71
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
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
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