ChatGPT解决这个技术问题 Extra ChatGPT

How to pass data to dialog of angular material 2

I am using dialog box of angular material2.

I want to pass data to the opened component. Here is how I am opening dialog box on click of a button

let dialogRef = this.dialog.open(DialogComponent, {
            disableClose: true,
            data :{'name':'Sunil'}
        });

On the documentation page there is data property, But I checked MdDialogConfig in my installed packages

/**
 * Configuration for opening a modal dialog with the MdDialog service.
 */
export declare class MdDialogConfig {
    viewContainerRef?: ViewContainerRef;
    /** The ARIA role of the dialog element. */
    role?: DialogRole;
    /** Whether the user can use escape or clicking outside to close a modal. */
    disableClose?: boolean;
    /** Width of the dialog. */
    width?: string;
    /** Height of the dialog. */
    height?: string;
    /** Position overrides. */
    position?: DialogPosition;
}

there is no data property in configuration class.

Now How can I access that passed data?


S
Saad Abbasi

For the newest version of dialog (This is prior to Angular 5, for 5 see update below), you can do the following to pass data via the config which is much simpler and cleaner.

When you open the dialog, you can do it this way by adding data as a config param (just ignore the width and height which is there for illustration purposes):

this.dialogRef = this.dialog.open(someComponent, {
  width: '330px',
  height: '400px',
  data: {
    dataKey: yourData
  }
});

Then in the component that is opened in the dialog, you can access it like:

import {MD_DIALOG_DATA} from '@angular/material';
import { Inject } from '@angular/core';


constructor(
   @Inject(MD_DIALOG_DATA) public data: any
) { }

ngOnInit() {
  // will log the entire data object
  console.log(this.data)
}

Or you can use access it in the template or other methods, but you get the point.

UPDATE for Angular 5

Everything in the material has been changed from Md to Mat, so if on Angular 5, import like:

import {MAT_DIALOG_DATA} from '@angular/material'

Then inject like

@Inject(MAT_DIALOG_DATA) public data: any

UPDATE for Angular 9

MAT_DIALOG_DATA import location has changed to:

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

Anyone who comes back and edits their posts with updated code for new framework versions gets an upvote, thanks!
This is the second time I've had to reference this answer and forgot to upvote it the last time.
The updated solution worked perfectly. Thank you.
Completely the right update! Thank you for the solution!
F
Fredrik Lundin

UPDATE 2 (Angular 5+)

This answer is rather outdated. Take a look at epiphanatic's answer instead.

UPDATE You can use dialogRef.componentInstance.myProperty = 'some data' to set the data on your component. You would need something like this: let dialogRef = this.dialog.open(DialogComponent, { disableClose: true, }); dialogRef.componentInstance.name = 'Sunil'; Then in your DialogComponent you need to add your name property: ... @Component({ ... }) export class DialogComponent { public name: string; ... }

Text below is not valid in newer versions of @angular/material

I didn't find any documentation on this, so i started looking into the source code too. Because of that, this might not be the official way of to do.

I successfully located the data in dialogRef._containerInstance.dialogConfig.data; So what you can do is for example let name = dialogRef._containerInstance.dialogConfig.data.name; console.log(name); // Sunil


dialogRef._containerInstance is undefined. I have checked MdDialogRef there is no property _containerInstance
@SunilGarg, you are right, I tried it with an older version of the library. With an update version, the data property is actually removed from the MdDialogConfig interface
I tried to update material lib but this is what I faced stackoverflow.com/questions/42667276/…
I have tried the same and tried to console.log(this.name); in constructor of DialogComponent. but not working
Well, you don't pass it to the constructor in this case, you set it after the component is created. So you need to check it in a later life cycle hook, or just bind it in your template @SunilGarg
D
Darren Street

I thought I'd give a fuller answer for those of us who are still learning:

Unlike the Material Examples I configured the dialog to have its own component files (html, css and ts) for ease of debugging.

Main component file "x.component.ts" (calling the dialog)

1) add the import statement

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

2) add the property to the constructor params

public dialog: MatDialog

3) define the code to call the dialog box

  openDialog(title: string, text: string): void {
const dialogRef = this.dialog.open(DialogComponent, {
  width: '350px',
  data: {dialogTitle: title, dialogText: text}
);

dialogRef.afterClosed().subscribe(result => {
});

  const dialogSubmitSubscription = 
  dialogRef.componentInstance.submitClicked.subscribe(result => {
  dialogSubmitSubscription.unsubscribe();
});

}

Call the function from your html file with openDialog(). I'm referencing DialogComponent so make sure its imported into your module.

import { DialogComponent } from './dialog/dialog.component';

also

entryComponents: [DialogComponent]

declare it in your entryComponents array

4) in your dialog.component.ts file, add the imports

import { Component, Output, EventEmitter, Inject, OnInit} from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';

5) define the properties & functions

dialogTitle: string;
dialogText: string;
@Output() submitClicked = new EventEmitter<any>();

  constructor(
    public dialogRef: MatDialogRef<DialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData) {}


  ngOnInit() {
    this.dialogTitle = this.data.dialogTitle;
    this.dialogText = this.data.dialogText;
  }

  saveMessage() {
    const data = 'Your data';
    this.submitClicked.emit(data);
    this.dialogRef.close();
  }

  closeDialog() {
    this.dialogRef.close();
  }

6) and lastly the HTML

<h1 mat-dialog-title>{{dialogTitle}}"</h1>
<div mat-dialog-content>
  <p>{{dialogText}}</p>

</div>
<div mat-dialog-actions>
  <button mat-button (click)="saveMessage()" >Ok</button>
  <button mat-button (click)="closeDialog()" cdkFocusInitial>No Thanks</button>

</div>

I hope it helps.


This was super helpful, thanks. While the documentation has this info, it wasn't very clear (to me anyway), and this helped me to get up and running. Thanks!
Super complete answer! Thanks!
exactly what I needed!
@Darren, hello thanks for this example. I get Cannot find name 'DialogData' Any idea?
The dialog data is the object you pass from the main component to the dialog component. @Inject(MAT_DIALOG_DATA) public data: DialogData. You inject it in the dialog constructor. the actual type is one you define yourself according to your needs. My example was called DialogData but could be anything or just an object literal
ס
סטנלי גרונן

For anyone that's finding this for angular 10 or 11, the only difference is that you use:

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

instead of:

import {MAT_DIALOG_DATA } from '@angular/material';

Official page is here.


j
jllangston

For Angular 13, to pass an object into the dialog data structure I had to use the following:

const dialogRef = this.dialog.open(MyDialog, {
  data: { myObjectHolder: myObject }
});

Then in the dialog class use this:

private myObject: MyObjectClass;

constructor(@Inject(MAT_DIALOG_DATA) data: { myObjectHolder: MyObjectClass }) {
    this.myObject = data.myObjectHolder;
}

T
TheDevGuy

So I have add the method and it's working on one component but if I want to make a dialog box (another component), it doesn't work

component of the table and delete button

  openDeleteDialog(user) {
    this.dialog.open(DeleteUserDialogComponent, {
      width: '30%', disableClose: true, data: user
    });
  }

Component dialog box

export class DeleteUserDialogComponent {

  dataSource = new MatTableDataSource();

  constructor(public dialog: MatDialog, public dialogRef: MatDialogRef<DeleteUserDialogComponent>, private userService: UserService, @Inject(MAT_DIALOG_DATA) public data: any) {}


  deleteUser() {
    this.dataSource.data.splice(this.dataSource.data.indexOf(this.data), 1);
    this.dataSource.data = [...this.dataSource.data];
    console.log(this.dataSource.data);
    console.log(this.data)
  }

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

b
blixenkrone

If you're using dialogs for HTTP data, remember RxJS and Observables is perfect for this issue.

Dialog service:

    private _dialogDataSubj$ = new Subject<DialogData>();
    dialogData$ = this._dialogDataSubj$.asObservable()

    setDialogData(data: DialogData) {
        this._dialogDataSubj$.next(data)
    }

In dialog HTML:

<ng-container *ngIf="dialogData$ | async as data; else doneTmp">

I'm not sure if it's just me, but i couldn't update data in my material dialog with just dialog data reference (@Inject) ie.: dialogRef.data = newData.


Also, have that kind of problem, and It turned out that I pass the wrong type of data, when want to update. You can update in two ways if you don`t want to use observables: 1. Use injected data object and assign a new one. 2. this.dialogRef.componentInstance.data = newData