6

How do you get data from an input field inside an Angular material dialog?

This is my code:

TS

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

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

export class SomeComponent implements OnInit {

  name: String;

  constructor(public dialog: MatDialog) { }

  ngOnInit() {
  }

  openDialog(): void {
    const dia = this.dialog.open(SomeDialogComponent, {
      width: "250px",
      data: { name: this.name }
    });

    dia.afterClosed().subscribe(result => {
      console.log("The dialog was closed");
      console.log("Your Name: " + this.name);
      this.name = result;
    });
  }
}

@Component({
  selector: "someDialog",
  templateUrl: "someDialog.html",
  styleUrls: ["someDialog.scss"]
})

export class SomeDialogComponent {

  constructor(public dialog: MatDialogRef<SomeDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any) { }

  onNoClick(): void {
    this.dialog.close();
  }
}

Dialog HTML

<body>
    <h1 mat-dialog-title>Enter your name</h1>

    <div mat-dialog-content class="contentBox">
        <mat-form-field>
            <input type="text" matInput>
        </mat-form-field>

        <div mat-dialog-actions>
            <button mat-raised-button (click)="onNoClick()">Exit</button>
            <button mat-raised-button (click)="sendData()">Ok</button>
        </div>
    </div>
</body>

I got this code from the Angular material's official documentation, https://material.angular.io/components/dialog/overview, but it is not working as expected.


Expected

I want the dialog to pass the data back the component without the use of a model, just a variable like I have put in my snippet.

Actual

The dialog does not pass the data back to the component and returns undefined instead when logged.

Compiler v2
  • 3,509
  • 10
  • 31
  • 55
  • 1
    You need to bind the Dialog's field to the `data` in the constructor. Using `[(ngModel)]` or `[(value)]` Most of the time your `data` will be an object (so it's easier to work with multiple fields) so your input field should be a property of data (like `data.inputField`) – Jojofoulk Jul 11 '19 at 00:06
  • I see, can you provide a code example of both cases? – Compiler v2 Jul 11 '19 at 00:07

1 Answers1

5
  1. you are not binding the input value to the data attribute you want
  2. you don't have a 'sendData()' method
  3. most importantly: you are logging the name before assigning the result value to it.

Update your dialog html code to this:

<body>
<h1 mat-dialog-title>Enter your name</h1>

<div mat-dialog-content class="contentBox">
    <mat-form-field>
        <input [(ngModel)]="data.name" matInput>
    </mat-form-field>

    <div mat-dialog-actions>
        <button mat-raised-button (click)="onNoClick()">Exit</button>
        <button mat-raised-button [mat-dialog-close]="data.name">Ok</button>
    </div>
</div>

It should work like that.

Green
  • 468
  • 5
  • 18
  • I have an error: `Can't bind to 'ngModel' since it isn't a known property of 'input'.` – Compiler v2 Jul 11 '19 at 00:17
  • Ah I fixed it: https://stackoverflow.com/questions/38892771/cant-bind-to-ngmodel-since-it-isnt-a-known-property-of-input – Compiler v2 Jul 11 '19 at 00:20
  • The logger still outputs `undefined` in the console, the data is still not being transmitted. – Compiler v2 Jul 11 '19 at 00:20
  • Hmmm, strange. I found that it gives me `undefined` the first time I input something. But when I reopen it again, the data is saved, and I press ok again, and this time it is sending the data through. – Compiler v2 Jul 11 '19 at 00:25
  • 1
    Sorry, my bad. It IS sending the data through the first time, it's just that the `console.log` seems to catch it the second time. Everything works now, thanks! – Compiler v2 Jul 11 '19 at 00:29
  • In my case I forgot to use the `[mat-dialog-close]` – Jnr Jan 14 '21 at 14:04