d4rty
d4rty

Reputation: 4188

Angular 5 - Data Change in Service doesn't reach Component

I have a shared-data.service.ts with some private properties, e.g.:

private _selectedId: string;

get selectedId(): string {
  return this._selectedId;
}

set selectedId(value: string) {
  this._selectedId = value;
}

I invoked this service in a component list.component.ts as a public object and used it directly in the component.

constructor(public sharedDataService: SharedDataService) {}
...
list: Defect[] = this.sharedDataService.getDefects(this.sharedDataService.selectedId)

Furthermore I used the service directly in the .html file of the component, i.e. list.component.html: <div>{{sharedDataService.selectedId}}</div>


When I now update the value of _selectedId in the service via another component I have the following problem:

Why do the html part get the update, but list: Defect[] doens't get the update ?

Upvotes: 0

Views: 1095

Answers (2)

JB Nizet
JB Nizet

Reputation: 692121

The instruction in your component is executed once, and only once, when the component is constructed. The list of defects is thus initialized at construction time, and has no reason to change. To change, the component would have to be aware that the selected ID has changed, and would have to call getDefects() again, and set the value of this.list again.

The expression sharedDataService.selectedId in your template, on the other hand, is reevaluated at each change detection of angular. So, every time some event is triggered, Angular reevaluates this expression, tests if it has a value that is different from before, and updates the DOM accordingly.

To refresh the list in the component, setting the selected ID should emit an event from an observable, that the component subscribes to, in order to refresh the list. As explained here: https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

Upvotes: 2

Ricardo
Ricardo

Reputation: 2497

Your view gets update because the lifecycle of your component is calling the method that gets the id every time that your move the mouse (print a console.log inside get selectedId() method... you will see ). and the list assignation is called only one time (I assume is in ngOnInit() ), you have to choices:

  • (the most ugly one ) Move the assignation of your list to ngOnChanges(changes: SimpleChanges) {} method. with that approach maybe your list will have the data that you want..
  • Use a subject to manage the Id in your service and subscribe to the data id in your component

Upvotes: 0

Related Questions