I've spent about 3 whole days trying to figure this out.
Behavior expected: Material Table always renders with most current data from backend. When a new item is added to table from a separate component, a router redirect to the page shows updated data.
Actual behavior: Upon first navigation to page, table is empty. Table is rendered, column headers rendered, but no rows populated. Navigating away then back populates the table properly. When adding a new item to the table, a service sends the item to the backend and then makes a call for all items. The service then updates the store (another service). On redirect to the table component the table seems to flash the old data quickly and then again appears blank. Once I navigate away and back the table is properly loaded.
I am using the async pipe below with services. This doesn't seem right to me... further, ngOnChanges logs nothing.
appStore.service.ts
private _pets: ReplaySubject<Pet[]> = new ReplaySubject(1);
public readonly pets: Observable<Pet[]> = this._pets.asObservable();
getPets(): Observable<Pet[]> {
return this.pets;
}
appDispatch.service.ts
public getPets(): Observable<Pet[]> {
return this.appStore.getPets();
}
private setPets(pets: Pet[]) {
this.appStore.setPets(pets);
}
petTableComponent.component.ts
...
changeDetection: ChangeDetectionStrategy.OnPush
constructor(private appDispatch: AppDispatchService,
private router: Router) {
}
ngOnChanges(changes: SimpleChanges): void {
console.log(changes.value.currentValue);
}
petTableComponent.component.html
<table
mat-table
[dataSource]="appDispatch.getPets() | async" multiTemplateDataRows
class="mat-elevation-z8">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef scope="col" [attr.role]="null"> <h4>Name</h4></th>
<td mat-cell *matCellDef="let element" scope="row" [attr.role]="null">
<p>{{element.pet.name}}</p>
</td>
</ng-container>
...
EDIT I tried changing the following per request, exact same outcome as before.
//changeDetection: ChangeDetectionStrategy.OnPush
pets-table.component.ts
constructor(private appDispatch: AppDispatchService,
private router: Router,
private cdr: ChangeDetectorRef) {
}
ngOnChanges(changes: SimpleChanges): void {
console.log(changes.value.currentValue());
}
ngOnInit(): void {
this.subscription = this.appDispatch.getReleaseItems()
.subscribe(value => {
this.data = value;
this.cdr.detectChanges();
});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
And I changed the datasource to [dataSource]="data"
Not sure...