Main component has tabs, component A, B etc.
My component_A has preloaded data but I have a button for filter. I have a button that toggles a drawer from another component (main component).
toggleDrawer(): void {
this.drawerService.toggleDrawer(); // Call service to toggle drawer
}
main component:
<mat-drawer-container class="drawer-container" autosize>
<div class="main-component-container">
<div class="mat-tab-grp">
<nav
class="nav-bar"
mat-tab-nav-bar
#tabGroup
mat-stretch-tabs
color="accent"
>
<a
mat-tab-link
*ngFor="let link of navLinks"
[routerLink]="link.link"
routerLinkActive
#rla="routerLinkActive"
[active]="rla.isActive"
>
<mat-icon>{{ link.icon }}</mat-icon>
{{ link.label }}
</a>
</nav>
<div class="ng-temp">
<router-outlet></router-outlet>
</div>
</div>
</div>
<mat-drawer
#drawer
class="example-sidenav mat-elevation-z2"
mode="side"
position="end"
>
<form [formGroup]="filterGroup" class="filter-fields">
some codes
</form>
</mat-drawer>
</mat-drawer-container>
ts file:
this.drawerService.toggleDrawer$.subscribe(() => {
this.drawer.toggle(); // Toggle the drawer
});
and this has button that fetches data
submitForm() {
this.dataService
.fetchData(someParameters)
.subscribe(
(response) => {
this.drawer.close(); //this closes the drawer then should update the mat-table in the component A.
}
}
in the dataService:
....this.dataSourceSubject.next(tmp_table);
After the drawer closes and the toggleDrawer() finishes, I want the mat-table to update too. It only updates when I go to other tabs, since this component A is in a mat-tab. That's the time it refreshes the table. I also can't make it reload the page because the preloaded data will be fetched again. So I just want the table to update.
I think the problem is that the BehaviourSubject
should emit the latest data from the API call and not the previous data.
fetchData(someParameters): Observable<any[]> {
return this.service.GetData(enc_param).pipe(
map((response: any) => {
this.dataSourceSubject.next(response); // <- changed here!
return tmp_ta
})
);
}
The problem could also be in how the mat-table and component A receive the data from your BehaviorSubject
.
In your service, make sure you have an observable of the BehaviorSubject.
dataSourceSubject: BehaviorSubject<any> = new BehaviorSubject<any>([]);
dataSourceObservable$!: Observable<any>;
constructor() {
this.dataSourceObservable$ = this.dataSourceSubject.asObservable();
}
Access this on the component using getter so that is can be used in HTML.
get dataSource$ () {
return this.dataService.dataSourceObservable$;
}
Finally when you make use of this property, use the async pipe.
<table mat-table [dataSource]="dataSource$ | async" class="mat-elevation-z8">
Same approach as above, but subscribe and get the data and send to the mat-table.
ngOnInit() {
this.sub.add(
this.dataService.dataSourceObservable$.subscribe((data: any) => {
this.data = data;
})
);
}
ngOnDestroy() {
this.sub.unsubscribe();
}
Finally when you make use of this property directly.
<table mat-table [dataSource]="data" class="mat-elevation-z8">