2

I am opening one dialog from my component.

 const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
             width: '500px',
            data: DialogData
            });

    dialogRef.afterClosed().subscribe(result => {
        this.dialogData = new DialogData('label...',this.frequency,'action','screen_ocr','parameter_type','parameter_value',0,'next_node',1,'index',false);
      console.log('The dialog was closed');

    });

I wan to access few properties from this component to initialize DialogOverviewExampleDialog

@Component({
  selector: 'dialog-overview-example-dialog',
  templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewExampleDialog {

    //here I want to use properties of my component

  constructor(private dialogService: DialogDataService,
    public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData) {}

The only way , I could figure out this is using behaviorsubject of rxjs to access properties, However this DialogOverviewExampleDialog is declared inside my component itself. Is there a way to directly access properties of my component inside DialogOverviewExampleDialog ? and vice versa as well.

Thanks,

Rajesh Kumar
  • 363
  • 2
  • 5
  • 13

4 Answers4

0

Use this: dialogRef.componentInstance.YOUR_PROPERTY

    const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
             width: '500px',
            data: DialogData
            });
    dialogRef.componentInstance.YOUR_PROPERTY

    dialogRef.afterClosed().subscribe(result => {
        this.dialogData = new DialogData('label...',this.frequency,'action','screen_ocr','parameter_type','parameter_value',0,'next_node',1,'index',false);
      console.log('The dialog was closed');

    });
jasonvuriker
  • 255
  • 1
  • 12
0

You can try this

component.ts Parent component from which we are opening dialog

import { Component, Inject } from '@angular/core';
import { VERSION, MatDialogRef, MatDialog, MatSnackBar, MAT_DIALOG_DATA } from '@angular/material';
import {ConfirmationDialog} from './confirm/confirmation-dialog.component';
@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  version = VERSION;

  constructor(private dialog: MatDialog,
    private snackBar: MatSnackBar) {
  }

  openDialog() {
    const dialogRef = this.dialog.open(ConfirmationDialog,{
      data:{name: 'Test1', from: 'Component'}  **// passing this data to dailog**
    });
    const snack = this.snackBar.open('Snack bar open before dialog');

    dialogRef.afterClosed().subscribe((confirmed: any) => {
     console.log(confirmed); **// after modal close data you will get here which passed from dialog on onConfirmClick() function**
    });
  }
}

confirmation-dialog.component.ts

import { Component, Inject } from '@angular/core';
import { VERSION, MatDialogRef, MatDialog, MatSnackBar, MAT_DIALOG_DATA } from '@angular/material';

@Component({
  selector: 'confirmation-dialog',
  templateUrl: 'confirmation-dialog.html',
})
export class ConfirmationDialog {
  message: string = "Are you sure?"
  confirmButtonText = "Yes"
  cancelButtonText = "Cancel"
  constructor(
    @Inject(MAT_DIALOG_DATA) private data: any,
    private dialogRef: MatDialogRef<ConfirmationDialog>) {
  console.log(this.data); **// Here is data recived from AppComponent.ts**
  }

  onConfirmClick(): void {
    this.dialogRef.close({name: 'Test', from: 'Dialog'}); **// on button click data will send to parent component after dialog close * AppComponent** 
  }

}
Santosh Shinde
  • 1,206
  • 10
  • 16
  • Here is demo https://stackblitz.com/edit/santosh-mat-dialog-example-data-sharing?file=app%2Fconfirm%2Fconfirmation-dialog.component.ts check console – Santosh Shinde Mar 03 '20 at 05:36
0

One possible solution of many others is to do it with the npm package @costlydeveloper/ngx-awesome-popup.

Which provides 2-way data binding between two components without breaking the object reference, the parent component (from where you call popup dialog) and child component (the one evoked inside the dialog). The child component can receive the data from the parent component and send a response payload object back.

In app.module.ts you can enable just the dialog module without importing other package features.

Import dialog module it in your AppModule:

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './app.component';

// Import your library
import {DialogConfigModule, NgxAwesomePopupModule} from '@costlydeveloper/ngx-awesome-popup';


@NgModule({
    declarations: [
        AppComponent
    ],
    imports     : [
        BrowserModule,

        // Enable package and dialog modules
        NgxAwesomePopupModule.forRoot(),
        DialogConfigModule.forRoot()
        // 
    ],
    providers   : [],
    bootstrap   : [AppComponent]
})
export class AppModule {
}

Setup of the ParentComponent

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

import {ChildComponent} from './child.component';

// import library classes
import {DialogLayoutDisplay, DialogInitializer, ButtonLayoutDisplay, ButtonMaker} from '@costlydeveloper/ngx-awesome-popup';

@Component({
    selector   : 'app-root',
    templateUrl: './app.component.html',
    styleUrls  : ['./app.component.scss']
})
export class ParentComponent implements OnInit {

    ngOnInit() {
        
        // Call the dialog.
        this.dialog();
    }

    // Create the method.
    dialog() {
        
        // Instance of DialogInitializer includes any valid angular component as an argument.
        const dialogPopup = new DialogInitializer(ChildComponent);
        
        // Any data can be sent to ChildComponent.
        dialogPopup.setCustomData({name: 'John', surname: 'Doe', id: 1});
        
        // Set some configuration.
        dialogPopup.setConfig({
            Width     : '500px',
            LayoutType: DialogLayoutDisplay.NONE // SUCCESS | INFO | NONE | DANGER | WARNING
        });
        
        // Set some custom buttons as list.
        // SUCCESS | INFO | NONE | DANGER | WARNING | PRIMARY | SECONDARY | LINK | DARK | LIGHT
        dialogPopup.setButtons([
            new ButtonMaker('Edit', 'edit', ButtonLayoutDisplay.WARNING), 
            new ButtonMaker('Submit', 'submit', ButtonLayoutDisplay.SUCCESS),
            new ButtonMaker('Cancel', 'cancel', ButtonLayoutDisplay.SECONDARY)
        ]);
    
        // Simply open the popup and listen which button is clicked and, 
        // receive optional payload from the ChildComponent.
        const subscription = dialogPopup.openDialog$().subscribe(resp => {
            // This is the response from the ChildComponent it will include 
your payload data and info about which button is clicked.
           
            // your payload data from the child component is here.             
            console.log('payload response: ', resp.Payload);

             
            if (resp.ClickedButtonID === 'submit') {
               // do some logic
            }
            subscription.unsubscribe();
        });
    }

}

Setup of the ChildComponent in a way to inject the DialogBelonging dependency in the Child component constructor, which will give you options to manipulate data and trigger the various events such as button click listener and closing loader. To send data back to ParentComponent just put your object as an argument to the close method like this: close(someObject), also you can implement simple logic to listen to which button is clicked and send different data. Your 2-way bound data sent from the ParentComponent is there this.dialogBelonging.CustomData

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Subscription} from 'rxjs';
import {DialogBelonging} from '@costlydeveloper/ngx-awesome-popup';

@Component({
    selector: 'app-any-angular-component',
    templateUrl: './any-angular.component.html',
    styleUrls: ['./any-angular.component.scss']
})
export class AnyAngularComponent implements OnInit, OnDestroy{
    
    subscriptions: Subscription[] = [];
    
    // Dependency Injection of the dialogBelonging in the constructor is crucial.
    constructor(private dialogBelonging: DialogBelonging) {}
    
    ngOnInit(): void {
        // Here is your 2 way data binded object with the Parent component.
        console.log(this.dialogBelonging.CustomData);
        
        // Subscribe to button listeners.
        this.subscriptions.push(
            // IDialogEventsController
            this.dialogBelonging.EventsController.onButtonClick$.subscribe((_Button) => {
                if (_Button.ID === 'edit') {
                    // Do some logic for example edit user.
                } else if (_Button.ID === 'submit') {  
                    // Do some logic and close popup.
                    this.dialogBelonging.EventsController.close();
                }
                else if (_Button.ID === 'cancel') {
                    
                    // Do some logic and close popup.
                    this.dialogBelonging.EventsController.close();
                }
            })
        );
        
    }
    
    ngOnDestroy(): void {
        
        // Care about memory and close all subscriptions.
        this.subscriptions.forEach(sub => sub.unsubscribe());
    }
}

Notice: For Angular 8: The packahe works with angular 9+ but because of the entry component rule which is deprecated from angular 9+, you will not be able to open the ChildComponent unless you add it to the entry component list in app.module.ts

entryComponents: [Childcomponent]
0

Why not use a service file to communicate between the dialog components and emitting data between them both.

This should give an idea of what i mean => https://www.dotnetcurry.com/angularjs/1445/angular-services-component-communication

jesvin palatty
  • 304
  • 2
  • 9