Hisham Mubarak
Hisham Mubarak

Reputation: 1609

Returning Data from MdDialog in Angular Material 2

I am using a MdDialogModule to show a Dialog window with an input field in it. The Modal is opening fine and I am able to enter text into input field and submit, but on clicking the Submit button, I want the data in the Input form to be returned to the Main Component that called the Dialog component and also close the Dialog.

How do I do this? I am able to pass data to MdDialog component, but didn't find any resource on how to return data to component from MdDialogComponent.

My Dialog component code looks like this

import { Component, OnInit, InjectionToken, Inject } from '@angular/core';
import { MD_DIALOG_DATA, MdDialogRef } from "@angular/material";

@Component({
  selector: 'app-add-book',
  templateUrl: './add-book.component.html',
  styleUrls: ['./add-book.component.css']
})
export class AddBookComponent {

  constructor() { }

}

and the method in main component calling the dialog box looks like this. No response is being returned now, it returns Undefined as I haven't figured it out yet.

openCreateDialog() {
    let dialogRef = this.dialog.open(AddBookComponent)
      .afterClosed()
      .subscribe(response => {
        console.log(response);
      });
  }

Upvotes: 34

Views: 40007

Answers (4)

Pran Kumar Sarkar
Pran Kumar Sarkar

Reputation: 1003

The other answers already answers the question. But let me provide a more verbose explanation of the solution I used in my use-case.

My requirement was to create a confirm Delete button in dialog. So I want to receive the result whether user confirmed to delete or not.

So my reusable Dialog component look like below:

import { Component, Inject } from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
import { ConfirmDialogDAO } from "./confirm.dialog.dao";

@Component({
    templateUrl: "./confirm.dialog.html"
})
export class ConfirmDialog {

    constructor(@Inject(MAT_DIALOG_DATA) public data: ConfirmDialogDAO,
                private dialogRef: MatDialogRef<ConfirmDialog>) {
    }

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

}

The above dialogRef is important because using that you can emit events based on user action on that component while dialog gets closed.

In my case, I only wanted to emit event when user clicked on confirm delete button. So the below is my html in dialog component:

<h1 mat-dialog-title>{{ data.title }}</h1>
<div mat-dialog-content>
  {{ data.description }}
</div>
<div mat-dialog-actions>
    <button mat-raised-button mat-dialog-close color="warn" (click)="yesButtonClicked()">{{ data.yesButtonName }}</button>
    <button mat-raised-button mat-dialog-close color="accent" cdkFocusInitial>{{ data.noButtonName }}</button>
</div>

If you notice, only when user clicks on +ve confirmation button, then I am emitting an event.

Now in the actual component where I wanted to reuse this dialog, this is how I invoked the dialog and performed action on data return:

import { MatDialog } from '@angular/material/dialog';

@Component({
  templateUrl: './another.component.html',
  styleUrls: ['./another.component.css']
})
export class AnotherComponent {

constructor(private dialog: MatDialog) { }

deleteInputNode(): void {
    this.dialog.open(ConfirmDialog, {
      data: {
        title: `Delete input node?`,
        description: `Please confirm:`,
        yesButtonName: `Delete`,
        noButtonName: `Cancel`
      },
    }).afterClosed().subscribe(data => {
      if (data) {
        alert("Delete"); // Perform one action
      } else {
        alert("Not delete");  // Perform another action
      }
    });
  }

}

So subscribing to afterClosed() event will give us access to data returned from dialog component.

In my case, I only returned true / false value, but you can also emit objects: {key: value}. So in that case you can access that data in afterClosed() subscription using data.key.

Resource: Refer to this live example from stackblitz in case my explanation lacks some details: https://stackblitz.com/edit/matdialog-return-data-demo-qqscz9?file=app%2Ffile-name-dialog.component.ts

Upvotes: 1

Rohan Shenoy
Rohan Shenoy

Reputation: 895

The "dialog.open" can be used to open the dialog component.

You can specify what data you would like to send to the dialog component by adding a second parameter. This can contain information like width and height check docs for more.

To close you can use ref.close().

If you want are expecting data from dialog then you can use ref.componentInstance.updatedSelectedArms which is an event fired when needed

var ref = this.dialog.open(SelectLoadingArmComponent, {
  width: '500px',
  data: { 
    loadingArms: this.loadingArms, 
    selectedloadingArms: this.selectedloadingArms
  }
});

ref.componentInstance.updatedSelectedArms.subscribe(
  (data) => {
    console.log(data)
    ref.close()
  }
);

Upvotes: 1

W Kenny
W Kenny

Reputation: 2069

Thanks for Harry's comment first...

below is the whole related script

Component ts:

  let dialogRef = this.dialog.open(DataListDialogComponent, dialogConfig).afterClosed()
  .subscribe(response => {
    console.log(response);
  });

dialog ts:

    this.dialogRef.close({data:'data'});

Upvotes: 20

Harry Ninh
Harry Ninh

Reputation: 16728

First, you need to add MdDialogRef to your dialog component

export class AddBookComponent {
  constructor(private dialogRef: MdDialogRef<AddBookComponent>) { }
}

Then use dialogRef.close to return the data

save() {
  this.dialogRef.close({ data: 'data' });
}

Upvotes: 61

Related Questions