3

In our Angular 4 app, we've a

  • <parent-component> which has a <form>
  • The <form> has <level-1-child>
  • The <level-1-child> has <level-2-child>
  • The <level-2-child> has <textarea>

What we need to do?

  • Reset the <form> elements of <parent-component>, <level-1-child> & <level-2-child> on <button> click or submit of <parent-component>'s <form>

<parent-component> looks like this:

<form [formGroup]="myGroup" #f="ngForm" name="parent-component" (submit)="resetForm(f)" >    
    <input name="abc" id="abc" formControlName="abc">    
    <level-1-child [formGroup]="myGroup"></level-1-child>    
    <input type="submit" value="Reset form">
</form>

And the <level-1-child> looks like this:

<input name="abc" id="abc" formControlName="abc">    
<level-2-child [formGroup]="myGroup">
</level-2-child>

And the <level-2-child> looks like this:

<div [formGroup]="myGroup">
    <textarea formControlName="abc" id="abc" name="abc" [(ngModel)]="level-2-child.txt" >
    </textarea>
</div>

The code of parent-component.ts, level-1-child.ts & level-2-child.ts is on the following lines:

import { Component, OnInit } from '@angular/core';
import { ReactiveFormsModule, FormGroup, FormControl } from '@angular/forms';

@Component({
    moduleId: module.id,
    selector: 'parent-component', //level-1-child, level-2-child
    templateUrl: 'parent-component.html' //level-1-child, level-2-child
})

export class ParentComponent {  //Level1Child, Level2Child
  myGroup = new FormGroup({abc: new FormControl()});
}

This code is only resetting the input#abc of <parent-component>. What is the fix for this?

What we have tried so far?

Tried solution 1

As per @StepanZarubin's suggestion, the parent-component.ts is like this:

resetForm(f) {    
    f.resetForm();    
}

with template <parent-component> like this:

<form #f="ngForm" (submit)="resetForm(f)" >
  <level-1-child>
    <level-2-child>
      <level-3-child>
        ...
          <level-n-child>
          </level-n-child>
        ...
      </level-3-child>
    </level-2-child>
  </level-1-child>
  <button type="submit"> Submit </button>
</form>

The template of <level-n-child> is:

<input name="inp" id="inp" #inpField="ngModel" [(ngModel)]="childModel.inp">

However for some reason, this is not resetting the input#inp element of <level-n-child>.

Tried solution 2

Tried solution 3

Can't bind to 'parentFormGroup' since it isn't a known property of 'level-n-child'

when tried to solve this error using REACTIVE_FORM_DIRECTIVES throws another error:

[ts] Module '"node_modules/@angular/forms/forms"' has no exported member 'REACTIVE_FORM_DIRECTIVES'.

However, we're already using the latest and this is not the main problem.

Tried solution 4

Tried solution 5

Possible solution

We don't wish to put a lot of messy code for input/outputs on these components.

Is there a way we can use something like shared services for this?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
  • 1
    Just FYI REACTIVE_FORMS_DIRECTIVES is deprecated and removed in Angular 2, RC6. You need to import ReactiveFormsModule instead. Also, any nested components (such as the ``, that contain input elements are not by default considered to be part of the parent's form. You need to manually notify the nested components that they are members of the form. (This is the solution you linked to with the words: "we're not considering this suggestion.) Then the reset may work? – DeborahK Jun 16 '17 at 20:08
  • @DeborahK Then how do we notify nested component that they are members of the form? – Zameer Ansari Jun 16 '17 at 20:13
  • 1
    You can keep passing the form group down. Alternatively, you could look at whether there are other ways to build the form without drilling down to so many levels. Maybe you could build a `` that can support any level instead of having so many nested components. – DeborahK Jun 16 '17 at 20:16
  • @DeborahK Please check my updated question. I have passed the form to child levels, but still it's not looking fine. And can you please explain the concept of ? – Zameer Ansari Jun 16 '17 at 23:04
  • To clarify, what do you mean by reset in your question? The .reset method only resets the form state. It does NOT clear the data. Is that what you meant? If you want to clear the data, you'll have to do that manually regardless of any other form techniques you use. – DeborahK Jun 16 '17 at 23:30
  • @DeborahK I wish to clear the data along with the view. In that case, what should the manual approach? – Zameer Ansari Jun 16 '17 at 23:32

1 Answers1

2

To initialize a form with "empty" data, I do something like this:

initializeProduct(): IProduct {
    // Return an initialized object
    return {
        id: 0,
        productName: null,
        productCode: null,
        tags: [''],
        releaseDate: null,
        price: null,
        description: null,
        starRating: null,
        imageUrl: null
    };
}

And then bind to the initialized product.

You can find a complete example here: https://github.com/DeborahK/Angular2-ReactiveForms (specifically the APM folder).

This code is for my "Angular Reactive Forms" course on Pluralsight if you want to see more details on how it was built: https://app.pluralsight.com/library/courses/angular-2-reactive-forms/table-of-contents

DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • This is something I'm doing however the problem is how do I let child component know that the parent wants it's `IProduct` to get empty? – Zameer Ansari Jun 16 '17 at 23:38
  • How are you sharing the data? If the data is shared between all of the child components, then the parent can simply set the bound property to the initialized product and the binding will take care of the rest. – DeborahK Jun 16 '17 at 23:41
  • I don't think there is any bound property as such in our app which all children have access to. – Zameer Ansari Jun 16 '17 at 23:58
  • Is there any way to build a plunker with the basics of your scenario that we could take a look at? It is getting difficult to assist further talking only in generalities. – DeborahK Jun 17 '17 at 00:01
  • I've shared the reproducible at this [plunk](https://embed.plnkr.co/dZvIOdxEb05mKtEPhbgT/) – Zameer Ansari Jul 20 '17 at 20:16