When the child component's form is marked as dirty, the parent component can access it

I have implemented a feature in my application that notifies users about pending changes on a form before they navigate away.

Everything works as expected, but I have a child component with its own form that needs to be accessed by the guard to check if it has unsaved changes.

How can I access this child component's form within the guard logic?

Guard:

import { CanDeactivate } from '@angular/router';
import { FormGroup } from '@angular/forms';
import { DialogService } from "ng2-bootstrap-modal";
import { ConfirmComponent } from '../components/confirm/confirm.component';
import { Inject } from '@angular/core';

export interface FormComponent {
    form: FormGroup;
}

export class PreventUnsavedChangesGuard implements CanDeactivate<FormComponent> {

constructor(@Inject(DialogService) private dialogService: DialogService) { }

canDeactivate(component: FormComponent): Promise<boolean> {

    if (component.form.dirty) {
        return new Promise<boolean>((resolve, reject) => {

            this.dialogService.addDialog(ConfirmComponent, {
                title: 'Unsaved Changes',
                message: 'You have unsaved changes. Are you sure you want to navigate away?'
            })
                .subscribe((isConfirmed) => {
                    return resolve(isConfirmed);
                });
        });
    }

    return Promise.resolve(true);
    }
}

Answer №1

Transfer the parent form as a parameter to the child component for seamless integration. The child component is responsible for linking its input fields with the parent form. If any changes are made to the child's input fields, it will automatically reflect on the parent form. This eliminates the need to directly manipulate the child form in your guard logic. Here is an example:

Parent Component TypeScript

import {FormBuilder, FormGroup} from "@angular/forms";
private parentComponentForm: FormGroup;
export class ParentComponent implements OnInit, OnDestroy {

    constructor(private _fb: FormBuilder) {}

    ngOnInit() {
        this.parentComponentForm = this._fb.group({});
    }
}

Parent Component HTML

<child-component
   [parentForm]="parentComponentForm"
</child-component>

Child Component TypeScript

export class ChildComponent implements OnInit {
   @Input() parentForm: FormGroup;      
   let inputFieldControl = new FormControl('', Validators.required);
   this.parentForm.addControl(this.inputFieldControlName, inputFieldControl);
}

Child Component HTML

<input type="text" class="form-control" [formControl]="parentForm.controls[inputFieldControlName]">

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

jQuery is malfunctioning following an AJAX request

Can anyone help me fix an issue with my jQuery code? I have a hidden div that should be shown when the mouse hovers over a sibling element. However, it seems like after my AJAX function is executed, the jQuery stops working. <div class="parent"> ...

What is the best way to define the type of an object in TypeScript when passing it to a function

I am currently working on a function that accepts an object of keys with values that have specific types. The type for one field is determined by the type of another field in the same object. Here is the code: // Consider this Alpha type and echo function. ...

Developing a separate NPM package for a portion of the app causes an increase in the total app size

Our projects utilize create-react-app and Typescript, resulting in the emergence of a collection of commonly used React components. To enhance maintenance and reusability, we decided to extract these components into their own NPM package named PackageA. Su ...

Conceal the Angular Material toolbar (top navigation bar) automatically when scrolling downwards

In my Angular application, the main navigation consists of a standard toolbar positioned at the top of the page. My goal is to have this navigation bar smoothly scroll up with the user as they scroll down, and then reappear when they scroll back up. I at ...

Uploading files with Angular 4 and Rails 5 using paperclip

I am currently engaged in a project that involves an Angular 4 frontend and a Rails 5 API backend. I'm facing an issue with uploading videos using paperclip, as they are not getting saved to the database for some unknown reason. Despite all the parame ...

The Select2 ajax process runs twice

I am encountering an issue with a script I have that retrieves data from the backend to populate a select2 dropdown. The problem is that the ajax call is being triggered twice every time, which is not the desired behavior. I'm unsure of what mistake I ...

The variable fails to receive a value due to an issue with AJAX functionality

I am struggling to figure out what's causing an issue with my code. I need to store the result of an AJAX request in a variable, specifically an image URL that I want to preload. $.ajax({ type: "POST", url: 'code/submit/submi ...

Selecting a GoJS Node using keys

In Angular with TypeScript, what is the best way to select a node from a diagram based on its key? Currently, I am required to left-click a newly created node in order to select it, but I would like for it to be automatically selected upon creation. I ha ...

What is the best way to create a number input field that also accepts text input?

The goal I have in mind is to create an input field that will contain text like "100%", "54vh", or "32px". I am attempting to utilize the number input's up and down arrows, while still allowing the user to edit the text. However, it should only allow ...

What exactly is the function of registerServiceWorker in React JS?

Just starting out with React and I have a question about the function of registerServiceWorker() in this code snippet: import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import registerServi ...

"Sequelize will pause and wait for the loop to finish before executing the

As someone with a background in PHP, I'm finding the concept of callbacks a bit challenging to grasp. Essentially, I need to retrieve some rows and then iterate through them to compare against another model (in a different database). However, I want ...

The error was thrown by the internal module loader in Node.js at line 1029

I encountered this Console Error - "Error: Cannot find module". Below is the detailed error message in the console. Any solutions? node:internal/modules/cjs/loader:1029 throw err; ^ Error: Cannot find module '/home/hiranwj/list' at Mo ...

Exploring Angular: The Dynamic Declaration of object.property in ngModel

<input [(ngModel)]="Emp."+"dt.Rows[0]["columnname"]"> This scenario results in an undefined value In my current project, I am leveraging the power of a MVC CustomHtmlHelper to generate textboxes dynamically based on database schema. The textbox ...

Error: Unable to process reduction on ships - function "reduce" is not functional

I created a boat visualization tool using a specific API. The API responds with a JSON that I then inject into a table. The issue: At times during the day, I observed the application would abruptly stop functioning and throw an error: Unhandled Rejection ...

Retrieve both the key and value from an array of objects

I have been scouring the internet for a solution to this question, but I haven't come across anything that fits my needs. Let's say we have an array of objects like this -- "points":[{"pt":"Point-1","value":"Java, j2ee developer"},{"pt":"Point ...

Dealing with all errors across all pages in Angular using a comprehensive error handling approach

I am currently using AngularJS and attempting to capture all errors across all pages. However, I am encountering an issue where it does not catch errors in some instances. For example, when I trigger a ReferenceError in one of the controllers, it is not be ...

Changing the bootstrap popover location

I'm looking to customize the position of a Bootstrap popover that appears outside of a panel. Here's my setup: HTML: <div class="panel"> <div class="panel-body"> <input type="text" id="text_input" data-toggle="popover ...

Transferring an object from Javascript to C++/CX following a C++/CX interface in Windows Runtime Components

As a newcomer to Windows Runtime Component, I've been exploring ways to accomplish the following task. I'm looking to extend a C++ interface in JavaScript. namespace MySDK { public interface class LoggerPlugin { public: virt ...

Using the RabbitMQ consume method in conjunction with the channel.ack function

I'm currently working on a function in TypeScript to consume messages from my RabbitMQ: async consume( queue: string, callback: (message: ConsumeMessage | null) => void, ) { return this.channel.consume(queue, message => { c ...

A guide on sorting an array based on elements from a different array

We are currently in the process of developing an application using Vue and Vuex. Our goal is to display a list of titles for venues that a user is following, based on an array of venue IDs. For instance: venues: [ {venue:1, title: Shoreline} {venue:2, ti ...