Reputation: 307
My angular is pretty basic. I have a view where I display an object (which is in a service):
<div *ngFor="let group of service.groups">
{{group.id}} - {{group.name}}
</div>
The simple version of my service looks like this:
public pushNewGroup(group) {
this.groups.push(group);
console.log('Pushing new group!');
// this.zone.run(() => {
// this.groups.push(group);
// });
}
public addGroup(group: Group) {
let component = this;
this.api.postWrapper('groups', group).then(function (data: Group) {
component.pushNewGroup(data);
});
}
If I create a button to call the service, everything works and the view updates:
<input type="button" (click)="pushGroup()" value="Add group/>
With service call in the view component:
pushGroup() {
let group = { ... }
this.service.pushNewGroup(group);
}
But if I call the promise through a dialog window then it doesn't update the view:
<li (click)="addGroup()" ><a>Add Group</a></li>
Component (simplified):
addGroup() {
let dialogRef = this.dialog.open(AddGroupComponent, {
data: {
...
},
});
}
export class AddGroupComponent {
constructor(private service: service) {}
addGroup(group: Group) {
this.service.addGroup(group);
}
}
I've tried both ngZone and ChangeDetectionStrategy.Default. Both solutions did not work for me. I can see that the object changes both times and the console log also works. But the view does not update.
My @Componment doesn't have anything interesting. For the whole class it's:
@Component({
templateUrl: './mainComponent.html',
styleUrls: ['./mainComponent.scss'],
providers: []
})
And for my add group dialog it is:
@Component({
selector: 'addGroup',
templateUrl: './AddGroupComponent.html',
styleUrls: ['./AddGroupComponent.scss'],
providers: [ApiService, PermissionsService, Service],
changeDetection: ChangeDetectionStrategy.Default
})
EDIT: It's very hard to extract the whole thing into plunker, but I tried recreating it and turns out the promise thing works. I think the fault might be with MatDialog. It doesn't update the main view. I tried recreating the whole thing in plunker, but I can't get angular material working in plunker. And it seems like all other examples on the net are broken as well:
https://embed.plnkr.co/LTAEwV6bNvoGQAFoky60/
Upvotes: 0
Views: 1806
Reputation: 8075
Why don't you use arrow function and forget this hack let component = this
? Maybe this can be the problem. Use the ES6 features, follow the angular styleguide.
public addGroup(group: Group) {
this.api.postWrapper('groups', group).then( (data: Group) => {
this.pushNewGroup(data);
});
}
Upvotes: 1
Reputation: 1518
Promise will postpone the change detection to the next detection cycle.
Try this:
Add private _cdr: ChangeDetectorRef
in the constructor.(obviously import ChangeDetectorRef
)
Add this._cdr.detectChanges()
inside promise (at the end).
Upvotes: 0