Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a service like this:

export class ArrService {
  private arr: any[] = [1,2,3];

  constructor() {}

  setValue(index: number, value: number): void {
    this.arr[index]= value;
  }

  addItem(value: any): void {
    this.arr.push(element);
  }

  removeItem(index: number): void {
    this.arr.splice(index, 1);
  }

  getItems(): Observable<any> {
    return of(this.arr);
  }
}

and I subscribe the getItems() observable in my component for my further purpose:

this.arrService.getItems().subscribe(res => {
  this._arr = res;
});

All the action is directly call the function in ArrService. When I called the setValue(), the source array in ArrService and local array in component both changed. And I record that the obseravble didn't emit again while change, so I guess that the obserables should be pass by reference.

But when I called the addItem() and removeItem(), the source change, but the local didn't. So the obserable isn't pass by reference? Or I'm misunderstanding how obseravble work?

I know subject or behaviourSubject can complete my service. But I wanna know how the observable functional in this case, why some action is follow but some doesn't.

question from:https://stackoverflow.com/questions/65559705/why-observable-result-wont-change-while-array-push-splice

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
184 views
Welcome To Ask or Share your Answers For Others

1 Answer

Try Subject

export class ArrService {
  private arr: any[] = [1,2,3];
  private arr$ = new Subject();

  constructor() {}

  setValue(index: number, value: number): void {
    this.arr[index]= value;
    this.arr$.next(this.arr);
  }

  addItem(value: any): void {
    this.arr.push(element);
    this.arr$.next(this.arr);
  }

  removeItem(index: number): void {
    this.arr.splice(index, 1);
    this.arr$.next(this.arr);
  }

  getItems(): Observable<any> {
    return this.arr$.asObservable();
  }
}

Use BehaviorSubject if you want to retain the last emitted value (useful in cases when you are subscribing after you have emitted value using .next() )


When you work with arrays, there is always problem associated to monitor any changes that has been made in it. You'll encounter similar behavior in other angular places as well where if you insert any new value to an array, the "ngOnChange" or even "zone.js" wont detect any change in value . In such cases, either you create new array reference or handle it manually.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...