Home > Enterprise >  How can I trigger a function from a modal component that does not include the function in Angular 14
How can I trigger a function from a modal component that does not include the function in Angular 14

Time:01-19

I have been developing an e-commerce app with Angular 14.

I am currently working on a form that *can only be submitted upon accepting the "Terms & conditions" displayed in a modal.

The FormComponent and ModalComponent are sibling components.

In form.component.ts I have:

import { Component } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { FormGroup, FormControl } from '@angular/forms';
import { ModalComponent } from '../modal/modal.component';

@Component({
  selector: 'my-app',
  templateUrl: './form.component.html',
  styleUrls: ['./form.component.css'],
})
export class FormComponent {
  public form: FormGroup = new FormGroup({});

  constructor(private dialog: MatDialog) {}

  ngOnInit() {
    this.form = new FormGroup({
      first_name: new FormControl(''),
      last_name: new FormControl(''),
      phone: new FormControl(''),
      email: new FormControl(''),
    });
  }

  public openDialog() {
    const dialogConfig = new MatDialogConfig();

    // Dialog options
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '420px';

    this.dialog.open(ModalComponent, dialogConfig);
  }

  public sendFormData() {
    console.log(this.form);
  }
}

In the form componant's template:

<h1>Get in touch</h1>

<form [formGroup]="form">
  <div >
    <mat-form-field appearance="outline" floatLabel="never">
      <mat-label >Fast name:</mat-label>
      <input  matInput formControlName="first_name" />
    </mat-form-field>

    <mat-form-field appearance="outline" floatLabel="always">
      <mat-label >Last name:</mat-label>
      <input  matInput formControlName="last_name" />
    </mat-form-field>

    <mat-form-field appearance="outline" floatLabel="never">
      <mat-label >Phone:</mat-label>
      <input  matInput formControlName="phone" />
    </mat-form-field>

    <mat-form-field appearance="outline" floatLabel="never">
      <mat-label >Email:</mat-label>
      <input  matInput formControlName="email" />
    </mat-form-field>
  </div>
  <div >
    <button (click)="openDialog()" mat-raised-button color="primary">
      Submit
    </button>
  </div>
</form>

In modal.component.ts I have:

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

@Component({
  selector: 'app-modal',
  templateUrl: './modal.component.html',
  styleUrls: ['./modal.component.css'],
})
export class ModalComponent implements OnInit {
  constructor(private dialogRef: MatDialogRef<ModalComponent>) {}

  ngOnInit(): void {}

  accept() {
    console.log('Terms accepted!');
  }

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

In modal.component.html I have:

<div mat-dialog-title>
  <h2>Terms & Conditions</h2>
</div>
<div mat-dialog-content>
  <p>
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur expedita
    ipsam assumenda sed non aut possimus, dolores ullam voluptates voluptatum
    distinctio aspernatur neque velit eum, eveniet voluptas omnis. Veritatis,
    architecto?
  </p>
  
</div>
<mat-dialog-actions>
  <button mat-raised-button color="primary" (click)="reject()">Reject</button>
  <button mat-raised-button color="primary" (click)="accept()">Accept</button>
</mat-dialog-actions>

I have put it all together in THIS Stackblitz.

The goal

The goal is to trigger the function sendFormData() from the form component from inside the accept() function of the modal component?

For achieving this, I did:

accept() {
    console.log('Terms accepted!');
    this.FormComponent.sendFormData();
}

The above does not work.

What is the easiest and most reliable way to achieve the desired result?

CodePudding user response:

In your dialog component, you pass a result to the close() function:

accept() {
  this.dialogRef.close('ACCEPTED');
}

reject() {
  this.dialogRef.close('REJECTED');
}

In your form component's openDialog() function, you handle the result:

public openDialog() {
  const dialogConfig = new MatDialogConfig();
  dialogConfig.disableClose = true;
  dialogConfig.autoFocus = true;
  dialogConfig.width = '420px';

  const dialogRef = this.dialog.open(ModalComponent, dialogConfig);
  dialogRef.afterClosed().subscribe((result) => {
    if (result === 'ACCEPTED') {
      this.sendFormData();
    }
  });
}
  • Related