Home > Enterprise >  Angular mat-dialog, refresh page upon submit and not close dialog
Angular mat-dialog, refresh page upon submit and not close dialog

Time:06-29

I'm new to angular (junior here) and in one of my tasks at work, had to fetch data from the database to fill the user grid. I managed to do that and the next step was to use the MatDialog, linked in a create new user button.

I fixed the creation services and linked it with the .NET controller, so now I had to make the component refresh the user data in grid so the new user would appear.

Tried some solutions like this one: How to refresh component after MatDialog close and data updated in database in Angular 6?

But I was unable to get anywhere, so I tried to use the window.location.reload() to achieve page reload and the new records start to appear.

I got a bug though, now when I open up the dialog to fill the fields of the new user information even if I hit the cancel button the page will be reloaded like when the new user submit event call.

Any suggestions on how to make the page refresh only when the submit button event is called (newUser) and the dialog closes and not when the user hit the cancel button?

Here is the open dialog with subscribe and the submit and cancel methods of the dialog:

1)User grid component with subscribe in order to reload the page

onAddUser() {
const dialogRef = this.dialog.open(AddUserRoleDialogComponent, {
  width: '500px',
  data: ''
}).afterClosed().subscribe(result => {
  this.getUsers().subscribe((data) => {
    this.users = data;
    console.log(data, 'data after refresh');
    console.log(this.users, 'users');
    this.dataSource = data;
  })
});
}

2)newUser method in dialog to call the api and create the user

newUser(model: any) {
return this.http.post<any>(url, model).subscribe({
  error: error => {
    this.errorMessage = error.message;
    console.error('There was an error!', error);
  }
});
}

3)Dialog cancel method which still refreshes the page

cancelSave(): void {
this.dialogRef.close();
}

CodePudding user response:

Rolling up the various comments into a single (hopefully) answer for you:

Per the comments, forcing a window reload on users should be a last last last resort.

Ideally, in scenarios such as this, you simply update the data client side (you know what you've created/updated/deleted so you can affect that change yourself).

This is typically the larger piece of work, sadly.

Next up is to go ahead and just make the API request again. Pretty simple, my personal favourite go-to because it's quick and, depending on what I'm working on, is 'good enough'.

Only as a last resort would you completely refresh the page. In general there's no need to. Your page(s) should be made up of individual components that you can push new data to, or tell to go re-fetch data. There's very few cases when you need to do a refresh.

Tackling issue number 1 - the continued force reload even on closing:

Per comments, this is a case of telling your component whether it should or shouldn't reload when it's closed. This is done with the this.dialogRef.close() method. You can give it something! E.g. a bool to decide if it should reload...

const dialogRef = this.dialog
    .open(AddUserRoleDialogComponent, 
        {
            width: '500px',
            data: ''
        }
    )
    .afterClosed()
    .subscribe((shouldReload: boolean) => {
        this.dialogRef.unsubscribe();
        if (shouldReload) window.location.reload()
    });

So when closing:

public onCancelSave(): void {
    this.dialogRef.close(false);
}

public onSave(): void {
    this.dialogRef.close(true);
}

For issue #2, the reloading itself:

Instead of doing a window reload, do your API request again instead of reloading the window...

if (shouldReload) this.myService.getData(...);

And for the third item - Angular change detection:

This actually depends on what you're using to display your data. The majority of things are probably fine just adding to the array - under the hood they're some form of loop. It's just a matter of what they check and how often they check it.

Angular, in general, won't notice property changes (i.e. if an object has a 'name' property and you change the name, Angular won't necessarily react to it).

What Angular WILL react to, is objects as a whole changing. The newer ES language features provide a nice simplified spread operator to help create 'new' objects that work well for triggering changes, for both objects and arrays:

this.someObject = {name: 'hello'};
this.someObject.name = 'world';
// No object-level change detection, but your template will likely update

this.someObject = {...this.someObject, name: 'world'};
// This is now a whole new object and everything looking 
// at it now knows it's something different and will re-evaluate

If, for example, that someObject was an input to a component, the component would have its change detection triggered in the second instance, but not the first.

Same is true with arrays - this.someArray = [...this.someArray].

  • Related