0

I have an EditItems component that's use for editing items. Inside the ngOnInit(), I subscribe to an observable that's in my dataService (a central Angular service for handling all of my data calls).

When the observable's data changes, my subscribe method is invoked:

ngOnInit() {
      this.myItemsSubscription = this.dataService.myItemsChanged
      .subscribe(
        (items: any[]) => {
          let lastItem = items[items.length - 1];

          if(lastItem.label.trim() === this.itemsForm.controls.label.value.trim()){
            this.id = lastItem.id;

            // *reference to 'this.editMode' below is always 'false'
            if (this.editMode){
              // do something
            }
          }
        }
      )
}

It appears that within the subscribe routine above, any references to properties within the current component are referring to the state of the component before the change that altered the observable.

For example I'm setting the value of this.editMode later on in ngOnInit, so that it's set to 'true' if a route with an id parameter is detected, however in the .subscribe above, it's still false (there's definitely nothing else that could be setting this back to false). I've verified that this is definitely referencing my component. If I reference this.editMode outside of the subscription to this.dataService.myItemsChanged, I get the correct value of true.

      this.route.params.subscribe((params: Params) => {
          this.editMode = false;

          if (Number(params['id']))
          {
            this.editMode = true;
          }
          this.initForm();
         }
      );
}

So, when I navigate to the route for an item, for an existing 'item', the above subscription is triggered, and this.editMode is set to true temporarily, but it's false when 'this.editMode' is referenced inside the first subscribe

Update

Properties of this are only referring to 'old' values when I create a new item (new items are also created with the 'EditItems' component), and then navigate to a different route, then navigate back to my item (with the 'id' on the route, so that this.route.params.subscribe is triggered)

Here are the relevant parts of my DataService. I'm declaring the myItemsChanged Subject as my Observable. myItemsChanged gets altered by a separate subscription that listens to a SignalR broadcast from the back end when the items are changed (the itemUpdated event)

@Injectable()
export class DataService {

  myItemsChanged = new Subject<any[]>();

  //Listening for the 'itemUpdated' event broadcast by SignalR from the back end
  let onItemUpdated$ = new BroadcastEventListener<any>('itemUpdated');

  this.connection.listen(onItemUpdated$);
  onItemUpdated$.subscribe((item: any) => {
    let index = this.items.findIndex(x => x.id === item.id);
    if (index > -1) {
      this.myItemsChanged.next(this.items.slice());
    }
  });

Why am I seeing false for the value of this.editMode inside the first subscription?

gotnull
  • 26,454
  • 22
  • 137
  • 203
Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206

1 Answers1

1

I wasn't unsubscribing the subscription, so when I was navigating to another route, then back to the route that contains my component, there was some kind of incorrect reference to the component inside my subscription.

This question about 'when to unsubscribe' provides an explanation and answer for what was causing this issue:

Angular/RxJs When should I unsubscribe from `Subscription`

When using Angular routing, navigating to another route calls the ngOnDestroy() method, and any subscriptions in that component should be unsubscribed inside that method like this:

ngOnDestroy() {
  this.myItemsSubscription.unsubscribe();
}

This ensures there are no memory leaks or unexpected results when re-subscribing the next time the component is accessed.

gotnull
  • 26,454
  • 22
  • 137
  • 203
Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206