Verify the validity of a form within an Angular 4 parent component

One of the challenges I am facing is checking the validity of a form located in a child component from a parent component. Ideally, I would like to be able to disable a button on the parent component if the form is invalid, or alternatively, trigger an alert from the parent component when the form is invalid.

To achieve this, I found a solution where I check if the form has the 'ng-invalid' class from the parent component by using a @ViewChild decorator to call a function on the child component. The code looks like this:

Parent Component:

export class CandidateVerificationComponent implements OnChanges, OnInit {

@ViewChild(RightPanelComponent) rightPanelPointer: RightPanelComponent;

saveAndFinish() {

    if (this.rightPanelPointer.checkFormValidity())
    {
        alert('No Valid');
        return;
    }

    this.rightPanelPointer.onSubmit();

}    
}

Child Component:

export class RightPanelComponent implements OnChanges , OnInit{

@ViewChild("candiateForm", { read: ElementRef }) tref: ElementRef;

   checkFormValidity():boolean {        
    return (this.tref.nativeElement.className.indexOf('ng-invalid') !== -1);
   }  
}

While this solution works for now, I am not entirely satisfied as it links the component to the DOM. I believe there must be a smarter approach to handle this.

My idea is to use a template reference variable (#candiateForm), similar to how we can check validity in the submit button below, in the form (child) so that I can verify the validity from the parent component. Is it possible to access that template variable from the parent?

 <form (ngSubmit)="onSubmit()" #candiateForm="ngForm" name="candiateForm" (change)="formChanged()">
    <div class="form-group">
      <label class="control-label" for="firstName">First name:</label>                           
      <input type="text" class="form-control" id="firstName" pattern="^[^0-9]+$" required [(ngModel)]='candidate.firstName' name="firstName" #firstName="ngModel">
   </div>
<button type="submit" class="btn btn-default" [disabled]="!candiateForm.form.valid">Submit</button>
</form>

Answer №1

Angular automatically applies the ngForm directive to all form elements, allowing you to reference any component or directive in the component template without the need for ElementRef or template references like #candiateForm. Instead, you can directly access the form using the directive class reference ngForm:

export class RightPanelComponent implements OnChanges, OnInit {
    @ViewChild(NgForm) form;

    checkFormValidity(): boolean {        
        return this.form.valid;
    }

Furthermore, you can also access the form directly from the parent component:

export class CandidateVerificationComponent implements OnChanges, OnInit {
    @ViewChild(RightPanelComponent) rightPanelPointer: RightPanelComponent;

    saveAndFinish() {
        if (this.rightPanelPointer.form.valid)

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

Having trouble rendering Next.JS dynamic pages using router.push()? Find out how to fix routing issues in your

The issue I am facing revolves around the visibility of the navbar component when using route.push(). It appears that the navbar is not showing up on the page, while the rest of the content including the footer is displayed. My goal is to navigate to a dy ...

I am interested in creating an input range slider using React and TypeScript

This code was used to create a slider functionality import { mainModule } from 'process'; import React, { useState } from 'react'; import styled from 'styled-components'; const DragScaleBar = () => { const [value, setV ...

Can we use a switch statement instead of having multiple @Input()s in Angular?

When passing an attribute into my Angular component like this: <my-component myAttribute></my-component> I aim to modify a variable within the component that controls the CSS properties for width and height. To simplify, I have predefined at ...

Why is it necessary to include the spread operator before an array of objects?

Currently delving into Angular and stumbled upon a code snippet that seems a bit cryptic to me. The function I'm working with returns an array of objects as Observable<Product[]>: connect(): Observable<Product[]> { const dataMutati ...

I am interested in identifying the TypeScript code within my library that is not being utilized. Any suggestions on how to achieve this?

What is the method to enable code lenses for TypeScript and identify sections with 0 references? Shown in this example image, which settings can indicate 0 references (similar to the grey font in the picture)? ...

What is the best way to transfer image files into a specific folder?

I am currently in the process of developing a ReactJS web application. My goal is to upload images to a specific folder and then store the file name in the database for future use. Everything seems to be working smoothly up to this point, but I am facing ...

A guide on extracting JSON Data and populating an Array in Angular 7

I have a JSON file stored locally containing various data. My goal is to extract the CityCodes specifically and store them in an array. Then, I plan to send these CityCodes as part of the OpenWeatherMap API request. Finally, I aim to display all the weathe ...

Utilizing D3 to fetch geographic data in the form of a TopoJSON file for U.S. counties

After retrieving a set of coordinates, the goal is to use D3 to find the corresponding county from a U.S. TopoJSON file. Here is an example code snippet: navigator.geolocation.getCurrentPosition(function(position) { let coordinates: [number, number] = [p ...

The module 'angular/common' was not found in the Angular 2 TypeScript

While experimenting with a sample login form in Angular 2, I encountered an issue when trying to import 'Form_Directives' as: import { FORM_DIRECTIVES } from '@angular/common'; An error was displayed stating that the angular/common m ...

While working on a project in React, I successfully implemented an async function to fetch data from an API. However, upon returning the data, I encountered an issue where it was displaying as a

I am working with React and TypeScript and have the following code snippet: const fetchData = async () => { const res: any = await fetch("https://api.spotify.com/v1/search?q=thoughtsofadyingatheist&type=track&limit=30", { met ...

Error message in Angular: Unable to locate a differ that supports the object '[object Object]' of type 'object.' NgFor is only able to bind to iterables like Arrays

When making an API call in my Angular project, I receive the following JSON response: { "data": { "success": true, "historical": true, "date": "2022-01-01", "base": "MXN&quo ...

Upgrade your @ngrx/store from version 10 to version 11 or 12

Hello there! I am in need of assistance regarding a specific issue. After updating our project to Angular 12 some time ago, I have been attempting to upgrade @ngrx/store from version 10 to either v11 or v12. Despite trying this update when we were still o ...

The directive does not function properly when used across multiple files

Struggling with @Directives and @Hostlisteners - seeking assistance The directive added to the input seems unresponsive, failing to trigger any events or console.log(). I'm puzzled and frustrated as there appears to be a missing piece of the puzzle t ...

Dragging and dropping elements onto the screen is causing them to overlap when trying

I am having trouble merging the drag and drop functionality from Angular Material with resizing in a table. Currently, both features are conflicting and overlapping each other. What I am hoping for is to automatically cancel resizing once drag and drop s ...

The state is not updated correctly by setState when the dropdown values are changed

Currently, I'm facing a situation where I have a dropdown that displays a user's accounts. Based on the selected account, the content of the page should change. I've tried an approach as shown below, but it seems like the setState method is ...

Ionic 4: Facing issues with setting complete background image on ion-card

https://i.stack.imgur.com/3lH6h.png I'm currently attempting to set a background image for an Ion-card in order to completely cover the card's area. However, I'm facing an issue where the background image does not cover the entire area and ...

Exploring the functionality of the Angular snackbar feature

I have created a simple snackbar with the following code: app.component.ts: ngOnInit(){ this.dataService.valueChanges.pipe( filter((data) => data === true), switchMap(() => { const snackBarRef = this.matSnackBar.open ...

After inputting new values, the table is not allowing me to update it

Recently acquainted with Angular, I am in the process of inserting new values and displaying them in a table using three components. These components include one for listing user information user-list, one for creating information rows user-form, and one f ...

The sourcemap for a Vue file based on TypeScript is not available due to the presence of the lang="ts" attribute

I am facing an issue where I need to transition my vue files from JavaScript to TypeScript. Currently, they have a standard structure like this: <template> ... </template> <script> ... </script> To use them with TypeScript, I le ...

How can I indicate separate paths for the identical dependencies listed in package.json?

Currently, I am in the process of working on an npm package that consists of an example directory designed to run and test the actual package. Within this example directory, I have re-integrated the parent package using "file:..". While this set ...