Exploring the concept of parent/child components in Angular 2 beta and how to efficiently validate form inputs from

My current project involves implementing a complex scenario in Angular2 (beta 0 with TypeScript in Plunker) that consists of two nested forms, each represented by a separate component.

The primary component, called Word, serves as a representation of a word within a simulated dictionary. The child components are instances of WordSense, each corresponding to a particular sense of the parent word.

Both components utilize model-driven forms, with the child form binding its model's values to form controls using ngModel. This setup allows for easy passage of the word's senses from the parent to the children through two-way bindings.

I have incorporated simple custom validators for both forms. One of my goals is to disable the submit button not only when the parent word form is invalid but also if any of its associated senses are deemed invalid. To achieve this, I introduced an isValid property to the model being edited, along with code to monitor changes in the sense form: whenever a change occurs, the form's validity is checked, and the model's property is adjusted accordingly. As a result, I can implement a validation check at the parent component level in both the view and code, ensuring that submissions are only made when both forms are validated.

In order to accommodate custom validation and additional logic, I transitioned from template-based to model-based forms. However, upon launching the refactored code, I encountered several errors stating "No Directive annotation found," the implications of which are unclear to me.

It's possible that I'm overlooking something obvious, given my newcomer status here. Could someone provide guidance or suggestions? For reference, you can access a reproducible example on this Plunker link: http://plnkr.co/edit/v9Dj5j5opJmonxEeotcR. Below are snippets of essential code excerpted from the example:

a) Parent Component:

@Component({
    selector: "word",
    directives: [FORM_DIRECTIVES, FORM_PROVIDERS, WordSense],
    templateUrl: `
<div>
<!-- Form content goes here -->
</div>
    `,
    inputs: [
        "word"
    ]
})
export class Word {
    // Class implementation
}

b) Child Component:

@Component({
    selector: "word-sense",
    directives: [FORM_DIRECTIVES],
    template: `
    <form>
    <!-- Form content goes here -->
    </form>
    `,
    inputs: [
        "sense",
        "ranks",
        "fields"
    ]
})
export class WordSense {
    // Class implementation
}

Answer №1

If you want more user-friendly error messages, consider switching from Angular2 .min.js files to the .dev.js versions.

By making this change, you may encounter the following error:

Error: No Directive annotation found on FormBuilder

The issue lies in assigning the FORM_PROVIDERS to the directives property of your component. This results in providers being treated as directives when they are not...

@Component({
  selector: "word",
  directives: [FORM_DIRECTIVES, FORM_PROVIDERS, WordSense], <-----
  templateUrl: `
    <div>
    (...)
  `
})
export class ...

To resolve this, simply remove it like so:

@Component({
  selector: "word",
  directives: [FORM_DIRECTIVES, WordSense], <-----
  templateUrl: `
    <div>
    (...)
  `
})
export class ...

Another issue is using templateUrl instead of template for the Word component:

@Component({
  selector: "word",
  directives: [FORM_DIRECTIVES, WordSense],
  templateUrl: ` <----------
  `
  (...)

Make sure to use the correct syntax:

@Component({
  selector: "word",
  directives: [FORM_DIRECTIVES, WordSense],
  template: ` <----------
  `
  (...)

For a revised example, check out the updated plunkr: http://plnkr.co/edit/x0d5oiW1J9C2JrJG8NdT?p=preview.

Hope these suggestions are helpful, Thierry

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

Can TypeScript convert JavaScript files automatically using a compiler?

Is there a way to use TypeScript files like this? <script type="text/typescript"> // ... </script> I came across https://www.typescriptlang.org/play/index.html, which can compile TypeScript. What compiler does this website use? I tried ...

When I click on a tab section to expand it, the carat arrows all point upwards. Only the arrows corresponding to the selected section should

click here for imageIt appears that there are four tabs, each with a click function on the carat icon. When I expand one tab, all carats point upwards instead of only the selected one appearing. accountSelection(account) { if (!this.selectedAccoun ...

Initiate asynchronous ngOnInit

Can ngOnInit() actually return a promise? I've noticed a common practice where developers use this approach and it appears to be functional. However, there is a risk with unobserved promises as they can be resolved or rejected at unexpected times, s ...

Heroku experiences a crash while attempting to import the 'aws-sdk' package

I currently have a Node.js app built using TypeScript that utilizes Amazon S3. This application is hosted on Heroku. import express from 'express'; import cors from 'cors'; //import aws from 'aws-sdk'; import dotenv from &apos ...

How can I replace this jQuery state change with the appropriate Angular code?

Within a component, I have a subject that triggers a .next(value) and initiates the following jQuery logic: if (this.isOpen) { jQuery(`#preview-${this.index}`). stop().slideDown('fast'); } else { jQuery(`#preview-${this.index}` ...

How can I include components in the precompile array in Angular2 RC4?

After upgrading my Angular2 project to RC4, the router started displaying a warning message in the console when I launch my application: router.umd.js:2466 'FrontpageComponent' not found in precompile array. To ensure all components referred to ...

Creating a Dynamic Table with Angular 6 - Automating the Population of Content Values

I have a task of populating a table with data from a JSON file. Take a look at the following code snippet: <table> <thead> <tr> <th *ngFor="let datakeys of listData[0] | keys">{{ datakeys }}</th> </tr> < ...

Cannot use a 'string' type expression to index a 'Request<ParamsDictionary, any, any, Query>' type

Currently, my goal is to develop a middleware that can validate the input data in a request. export function validator(schema: Joi.ObjectSchema, key: string) { return function (req: Request, res: Response, next: NextFunction): void { try { Joi ...

Adding an external JavaScript file to an Angular 5.0.0 project

Struggling to integrate hello.js into my Angular 5.0.2 project. See the CLI version below https://i.sstatic.net/RcGz5.jpg I have included the script file in angular-cli.json. "scripts": [ "./js/hello.js", "./js/hello.polyfill.js", ...

Building on Angular 7, generate a fresh object by extracting specific values from an existing object

My object structure is as follows: const Obj = "Value1": { "value1value": "1" }, "Value2": { "value2value": "2" }, "Value3": { "value3value": "3" }, "BTest": { "1": "1", "2": "2" }, "Value4": { "value4value": "value4value" }, "ATes ...

"Trouble arises with the implementation of the routerLink directive

I have been developing an Angular2 application that involves routing with the component router. Currently, I am using angular-2.0.0-beta.3. When trying to use the routerlink directive in a child component, my template looks like this: <a [routerLink] ...

Injecting a service into a parent class in Angular 6 without the need to pass it through the constructor

Can anyone provide guidance on how to incorporate a service with multiple dependencies into an abstract class that will be inherited by several classes, in a more streamlined manner than passing it through all constructors? I attempted to utilize static m ...

Error: TypeScript is unable to locate the 'moment' module

My TypeScript React application was set up using npx create-react-app --template typescript. However, when I try to start the app with npm start, I encounter an error in one of my files: TypeScript error in /<path>/App.tsx: Cannot find module ' ...

Generating a sequential array of dates and times in Angular

Currently, I am working on implementing a feature that will allow users to see the available visit times between two dates they select, specifically from 8:00 to 17:00 every day. For instance: If a user selects 1 Sep to 4 Sep, the system should return [1. ...

Encountering an error while trying to run NPM install

I have attempted to uninstall and reinstall angular cli by using the following commands: sudo npm uninstall -g @angular/cli sudo npm install -g @angular/cli However, every time I run npm install, I encounter the following error: npm ERR! Unexpected toke ...

Ways to utilize Subjects for sharing global information in Angular 6

I have been struggling to find an effective way to share data between two components that have the same parent in an Angular application. Currently, I am working with an Angular Material stepper where Step 1 contains one component and Step 2 contains anot ...

What kind of impact does the question mark at the conclusion of a function title make?

I came across the following TypeScript code snippet: class Foo { start?(): void {} } What caught my attention was the ? at the end of start. It appears to be making the function optional (but how can a function be optional and when would you need tha ...

ExpressJs Request Params Override Error

I am currently utilizing express version 4.19.2 (the latest available at the time of writing) This is how I have declared the generic type Request interface ParamsDictionary { [key: string]: string; } interface Request< P = core.ParamsDictionary, ...

Angular unable to properly display image

When trying to display an image in my Angular 6 app using the following line of code: <img src="https://unsplash.com/photos/DOrhbkYbFkg"> Instead of the expected picture, only a small square with a question mark is displayed: https://i.sstatic.net ...

I have encountered an issue where I am unable to include any additional classes in my next.js 13 component that is displaying sanity data inside a portableText element

I've been experimenting with various methods to style my elements. Attempted solutions include creating a custom component and passing it to the PortableText element, as well as directly adding the component to the PortableText element. import { cli ...