I have been stuck with this for two days and I hope someone can point me to a solution. I have an Angular application using Akita for state management and one of the components is tasked with loading a list of customers. I have placed the important bits of my code below.
// customers.component.ts
export class IndexComponent implements OnInit, AfterViewInit, OnDestroy {
// Constructor and other definitions are here
customers$: Observable<Customer[]>;
@ViewChild(MatPaginator) private _paginator: MatPaginator;
@ViewChild(MatSort) private _sort: MatSort;
ngOnInit(): void {
this.customerService.get().subscribe();
this.customers$ = this._customersQuery.customers$;
}
ngAfterViewInit(): void {
if (this._sort && this._paginator) {
// Code here is never executed
}
}
}
// customer.service.ts
export class CustomerService extends NgEntityService<CustomerState> {
// Constructor is here
get() {
return this.http.get<Customer[]>('/api/customers').pipe(
tap(entities => {
this.CustomerStore.set(entities);
})
);
}
}
// customer.query.ts
export class CustomerQuery extends QueryEntity<CustomerState> {
public customers$: Observable<Customer[]> = this.selectAll();
constructor(protected store: CustomerStore) {
super(store);
}
}
// customer.component.html
<ng-container *ngIf="(customers$ | async) as customers">
<ng-container *ngIf="customers.length > 0; else noCustomers">
// The table goes here
<mat-paginator>
// Paginator options go here
</mat-paginator>
</ng-container>
</ng-container>
<ng-template #noCustomers><p>No Customers</p></ng-template>
No matter what I do, I always get an undefined
Paginator instance. I am not sure what I am doing wrong. I would appreciate any assistance. Thank you.
The problem is that the element that you are using ViewChild
on is in an ngIf
:
@ViewChild(MatPaginator) private _paginator: MatPaginator;
The paginator you are trying to bind to isn't in the DOM when the component is initialized, because it's hidden by the ngIf
, therefore the binding doesn't occur.
This is a long discussion on how to get around this issue.
The TLDR solution is to use bind to the native HTML hidden
property and flip your ngIf
logic. That's not so simple with your code because of the nesting of ngIf
s and using ng-container
s, not div
s.