'Angular 13 - material table new row, delete row update table
I am using Angular 13 material-table. I am able to successfully send a request to an api server.
I'm sending a successful post request using modal-dialog and registering. But I can't see it on the current table after registering, I see it in the table after refreshing the page.
Likewise, when I delete a record, it is not deleted from the table, I can see it in the table after the page is refreshed.
How can I fix this?
Here is the "material request lists" where my main table is located, in this area my table is available
material-demands-list
export class MaterialDemandsListComponent implements OnInit {
displayedColumns: string[] = [
'id',
'description',
'createdUserId',
'createdUserName',
'status',
'companyId',
'companyName',
'actions',
];
materials: MaterialDemandsModel[] = [];
dataSource = new MatTableDataSource<MaterialDemandsModel>(this.materials);
@ViewChild(MatPaginator, { static: false }) paginator!: MatPaginator;
@ViewChild(MatSort, { static: true }) sort!: MatSort;
@ViewChild(MatTable, { static: true }) table: MatTable<any> | any;
page: number = 1;
pageSize: number = 10;
totalCount: number = 0;
pageSizeOptions: number[] = [5, 10, 20, 50, 100];
workflows: WorkflowListModel[] = [];
constructor(
private messageService: MessageService,
public demandsService: MaterialDemandService,
public workflowService: WorkflowListService,
public dialog: MatDialog
) {}
ngOnInit(): void {
this.getData(this.page, this.pageSize);
this.dataSource.paginator = this.paginator;
this.workflowService.getWorkflowDefinitions().subscribe((data) => {
this.workflows = data.items;
});
}
getData(page: Number, pageSize: Number) {
this.demandsService
.getMaterialDemands(Number(page), Number(pageSize))
.subscribe((data) => {
this.dataSource.data = data.data;
this.totalCount = Number(data.data[0].totalCount);
this.demandsService.loading = false;
});
}
deleteDialog(obj: any): void {
Confirm.show(
`Delete row : ${obj.id}`,
`${obj.description} selected row deleting ?`,
'Delete',
'Cancel',
() => {
this.demandsService.deleteMaterialDemand(obj.id).subscribe({
next: (v) => {},
error: (e) => {
console.log(e);
},
complete: () => {},
});
},
() => {
alert('Cancel');
}
);
}
onChangePage(pageEvent: PageEvent) {
this.pageSize = pageEvent.pageSize;
this.page = +pageEvent.pageIndex + 1;
this.getData(this.page, this.pageSize);
this.demandsService.loading = true;
}
openDialog(action: any, obj: any) {
obj.action = action;
const dialogRef = this.dialog.open(MaterialDemandDialogComponent, {
data: obj,
autoFocus: false,
});
dialogRef.disableClose = true;
// send message to subscribers via observable subject
this.messageService.sendMessage(this.workflows);
dialogRef.afterClosed().subscribe((result) => {
console.log(result);
if (result.event == 'Add') {
this.addRowData(result.data);
} else if (result.event == 'Update') {
this.updateRowData(result.data);
}
});
}
addRowData(row_obj: any) {
console.log(row_obj);
this.materials.push({
id: 'row_obj.id',
description: 'row_obj.description',
ldapId: 'row_obj.ldapId',
sAMAAccountName: 'row_obj.sAMAAccountName',
objectGuid: 'row_obj.objectGuid',
email: 'row_obj.email',
preferredUserName: 'row_obj.preferredUserName',
manager: 'row_obj.manager',
companyName: 'row_obj.companyName',
status: 'row_obj.status',
companyId: "row_obj.companyId",
workflowId: 'row_obj.workflowId',
workflowDefinitionId: 'row_obj.workflowDefinitionId',
workflowName: 'row_obj.workflowName',
workflowVersion: "row_obj.workflowVersion",
totalCount: "row_obj.totalCount",
});
this.table.renderRows();
}
updateRowData(row_obj: any) {
this.materials = this.materials.filter((value, key) => {
if (value.id == row_obj.id) {
value.description = row_obj.description;
}
return true;
});
}
}
In this modal form screen, I am creating a new record or updating an existing record.
material-demand-add-update-dialog
export class MaterialDemandDialogComponent implements OnInit, OnDestroy {
action: string | any;
local_data: any;
workflows: WorkflowListModel[] = []; //Workflow list
workflowsCtrl = new FormControl(); //autoComplete states
filteredStates: Observable<string[]> | any;
subscription: Subscription | any;
errorMessage = '';
@Input() material = {
description: '',
ldapId: '',
sAMAAccountName: '',
objectGuid: '',
email: '',
preferredUserName: '',
manager: '',
companyName: '',
status: 'Boşta',
workflowId: '',
workflowDefinitionId: '',
workflowName: '',
workflowVersion: '',
companyId: '1',
};
ownerForm: FormGroup | any;
constructor(
private fb: FormBuilder,
private messageService: MessageService,
private materialDemandService: MaterialDemandService,
public dialogRef: MatDialogRef<MaterialDemandDialogComponent>,
@Optional() @Inject(MAT_DIALOG_DATA) public data: MaterialDemandsModel
) {
this.local_data = { ...data };
this.action = this.local_data.action;
// subscribe to material-demands-list component -> workflow list messages
this.subscription = this.messageService
.getMessage()
.subscribe((message) => {
this.workflows = message.message;
if (message) {
//this.workflows.push(message.message);
} else {
this.workflows = [];
}
});
}
ngOnInit(): void {
this.filteredStates = this.workflowsCtrl.valueChanges.pipe(
startWith(''),
map((state) =>
state ? this._filterStates(state) : this.workflows.slice()
)
);
//Validators
this.ownerForm = this.fb.group({
description: [
this.local_data.description,
[Validators.maxLength(250), Validators.required],
],
workflowName: [
this.local_data.workflowName,
[Validators.maxLength(150), Validators.required],
],
});
}
setWorkflowInfo(value: any) {
this.material.workflowName = value.name;
this.material.workflowDefinitionId = value.definitionId;
this.material.workflowId = value.id;
this.material.workflowVersion = value.version;
}
postMaterialDemand(): void {
this.materialDemandService
.postMaterialWithObservable(this.material)
.subscribe({
next: (v) => {
console.log(v);
},
error: (e) => {
this.errorMessage = e;
console.log(e);
},
complete: () => {
console.log('success');
},
});
}
doAction() {
if (this.action === 'Add') {
this.postMaterialDemand();
}
this.dialogRef.close({ event: this.action, data: this.local_data });
}
closeDialog() {
this.dialogRef.close({ event: 'Cancel' });
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
My service file is as follows. I make sites like "Get, Post, Delete" here and it returns successfully.
service
export class MaterialDemandService {
private gatewayUrl: string = `${environment.gatewayUrl}`;
public loading: boolean = true;
constructor(private httpClient: HttpClient) {}
httpHeaders = new HttpHeaders({
'Content-Type': 'application/json',
});
//GATEWAY -> POST
postMaterialWithObservable(data: any): Observable<MaterialDemandsModel> {
let api = `${this.gatewayUrl}/api/services/purchasing/MaterialDemands`;
return this.httpClient
.post<any>(api, JSON.stringify(data), {
headers: this.httpHeaders,
})
.pipe(
tap((x) => {
this.loading = false;
}),
retry(2),
map(this.extractData),
catchError(this.handleError)
);
}
//GATEWAY -> GET -> get material demands 1/10
getMaterialDemands(page: number, pageSize: number) {
return this.httpClient
.get<{ data: MaterialDemandsModel[] }>(
`${this.gatewayUrl}/api/services/purchasing/MaterialDemands/${page}/${pageSize}`
)
.pipe(
retry(2),
tap((x) => {
this.loading = false;
}),
catchError(this.handleError)
);
}
deleteMaterialDemand(materialId: Number) {
return this.httpClient
.delete<any>(
`${this.gatewayUrl}/api/services/purchasing/MaterialDemands/${materialId}`,
{ headers: this.httpHeaders }
)
.pipe(retry(2), catchError(this.handleError));
}
private extractData(res: any) {
return res;
}
private handleError(error: any) {
let errorMessage = '';
if (error.errorMessage instanceof ErrorEvent) {
errorMessage = error.error.errorMessage;
} else {
errorMessage = `\nCode: ${error.status}}\nResponse: ${error.message}`;
}
window.alert(errorMessage);
return throwError(() => {
return errorMessage;
});
}
}
I've been working on it for a few days but I couldn't figure it out.
Solution 1:[1]
I belive you have to provide a new refference for dataSource
In case of adding a new row you have to do something like this
this.dataSource = [...this.dataSource, newRow];
In case of deleting
this.dataSource = this.dataSource.filter(...)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |