How to use material table with async pipe and change detection? (Not working properly)

Discussão em 'Angular' iniciado por cyberguy, Novembro 3, 2024.

  1. cyberguy

    cyberguy Guest

    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...

    Continue reading...

Compartilhe esta Página