Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to communicate from mat dialog component to the component where mat dialog is implemented?

I have a dialog component and app component where the material dialog is implemented. Here is the code of app component

import { Component } from '@angular/core';
import {VERSION, MatDialog, MatDialogRef} from '@angular/material';
import { DialogComponent } from '../dialog.component';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  DialogRef: MatDialogRef<DialogComponent>;
  constructor(private dialog: MatDialog) {}
  ngOnInit() {
  }
  addItem() {
    this.DialogRef = this.dialog.open(DialogComponent);
  }

receiveMessageFromDialogComponent() {
  // how to receive message from dialog component
}
closeDialog(): void {
  this.DialogRef.close();
}
}

The dialog component is where the form is implemented, I need to take the form value and receive it in here. I tried using angular input and output to achieve this but dint work coz there is no child and parent communication. Here is the Dialog component

import { Component } from '@angular/core';

@Component({
  template: `
    <h1 mat-dialog-title>Add Item</h1>
    <mat-dialog-content>
    <mat-form-field  class="example-full-width">
        <input matInput placeholder="Item name here...">
    </mat-form-field>
    </mat-dialog-content>
    <mat-dialog-actions>
      <button mat-button (click)="saveMessage()">Add</button>
      <button mat-button (click)="closeDialog()">Cancel</button>
    </mat-dialog-actions>
  `
})
export class DialogComponent {
  saveMessage() {
    console.log('how to send data to the app component');
  }
  closeDialog() {
    console.log('how to close');
  }
}

Working Example on StackBlitz

like image 479
karty Avatar asked Dec 23 '17 12:12

karty


People also ask

How can I get data from Mat dialog?

You can pass any kind of data to the component by adding data to the MatDialog's open() options. }, }); You can retrieve the data by injecting MAT_DIALOG_DATA in the opened component.

How do you use mat dialog?

First we need to import 'MatDialog' from '@angular/material/dialog' and we need to create an instance for it in the constructor. Using this instance we can open the dialog box component. Now create a separate component for the dialog and write code as per the requirements.

What is MatDialogRef in angular?

The MatDialogRef provides a handle on the opened dialog. It can be used to close the dialog and to receive notifications when the dialog has been closed. Any notification Observables will complete when the dialog closes. dialogRef. afterClosed().


2 Answers

A use case scenario if you want to edit some data in a dialog then pass the edited data back to the component from the dialog. I used the example above but I consolidated the answer to make it easier to follow. Assuming the data is coming from a service this example shares data from a mat-dialog component to an app component in the same file.

// app.component.html  

<div *ngFor="let a of appData">
  <p>{{a.name}}</p>
<button> (click)="open(event, a)">edit</button> 
</div>
// app.component.ts    

import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
 appData: Array <any>;

 constructor(private dataService: DataService, public dialog: MatDialog) {}

 ngOnInit() {

   this.dataService.getData()
    .subscribe(res => { 
      //console.log(res);
      this.appData = res;
   })
 }

public open(event, data) {
  this.dialog.open(EditDialog, {
    data: data,
}).afterClosed()
  .subscribe(item => {
    // Edited Data sent to App Component from Dialog 
    console.log(item);
  });
 }
}

@Component({
  selector: 'edit-dialog',
  template: `<span>Edit Data</span>
             <mat-dialog-content>
               <input matInput name="title" type="text" class="form-control" placeholder="Edit Name" [(ngModel)]="dataItem.name">
             </mat-dialog-content>
             <div>
               <span><button mat-raised-button (click)="updateData()">Update Recipe</button></span>
             </div>`,
 })

 export class EditDialog implements OnInit {

   dataItem: any;  

   constructor(public dialogRef: MatDialogRef <EditDialog> , @Inject(MAT_DIALOG_DATA) public data: any, private dataService: DataService) {
     this.dataItem = this.data;
   }

   public updateData() {
     this.dialogRef.close(this.dataItem);
   }

   ngOnInit() {
   }
}
like image 65
Ian Poston Framer Avatar answered Oct 03 '22 05:10

Ian Poston Framer


You can actually achieve communication using subscription to @Output through MatDialogRef<DialogComponent>. For some scenarios, you may need to get the data from a dialog before it is closed. Hence, we cannot make use of the this.DialogRef.afterClosed() function since we have to close the dialog first to get the data. Instead, we want to get the Component instance and access from there.

On your DialogComponent:

export class DialogComponent {
 
  @Output() submitClicked = new EventEmitter<any>();

  constructor(public dialogRef: MatDialogRef<DialogComponent>){}

  saveMessage() {
    this.submitClicked.emit('Your data');
  }

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

On your AppComponent:

openDialog() {
    this.dialogRef = this.dialog.open(DialogComponent);
    this.dialogRef.componentInstance.submitClicked.subscribe(result => {
        console.log('Got the data!', result);
    });
}

Better make sure to unsubscribe() all your Subscriptions. Something like this will do for a quick unsubscribe (if there's no validation of data involved):

const dialogSubmitSubscription = this.dialogRef.componentInstance.submitClicked
    .subscribe(result => {
      console.log('Got the data!', result);
      // do something here with the data
      dialogSubmitSubscription.unsubscribe();
    });

Also, you can always close your dialog from the AppComponent with this.dialogRef.close() if you have to. Or in the example above, you can also use the this.DialogRef.componentInstance.closeDialog().

like image 24
Cold Cerberus Avatar answered Oct 03 '22 05:10

Cold Cerberus