4

I have a component A(child) which I want to display under component B(parent). Component "A"

<div [formGroup]="dbForm">
    <div class="form-group">
      <label class="form-label" for="dbServerID">Exposure Server</label>
      <div>
        <select formControlName="dbServer" class="form-control custom-select" id="dbServerId">
          <option *ngFor="let ds of databaseServers" [ngValue]="ds">
            {{ds.databaseServerName}}
          </option>
        </select>   
      </div>
    </div>
  </div>

Typescript page of control "A"

@Component({
  selector: 'app-database-server',
  templateUrl: './database-server.component.html',
  styleUrls: ['./database-server.component.css']
})
export class DatabaseServerComponent implements OnInit {
  dbForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.createForm();
  }
  createForm() {
    this.dbForm = this.fb.group({
      dbServer: ['', Validators.required ]
    });
  }

Html page of Component "B"

<form [formGroup]="newPfForm">
  <div class="form-group">
    <label class="form-label">Name</label>
    <input class="form-control" type="text" formControlName="name" />
  </div>
  <div>
    <app-database-server ></app-database-server>
  </div>
</form>
<p>Form value: {{ newPfForm.value | json }}</p>

Typescript of Component "B"

@Component({
  selector: 'app-new-portfolio',
  templateUrl: './new-portfolio.component.html',
  styleUrls: ['./new-portfolio.component.css']
})
export class NewPortfolioComponent implements OnInit {
  newPfForm: FormGroup;

  constructor(private fb: FormBuilder) {
  }

  ngOnInit() {
    this.newPfForm = this.fb.group({
        name: ['', [Validators.required, Validators.maxLength(10)]],
        dbForm: this.fb.group({
          dbServer: ['', Validators.required],
        })
    });
}

Now when I enter anything in the textbox of parent component it's visible in From value but if I select drop-down of child component, form value is not updating. Even I have spent 2 hrs but I am not able to find my mistake. screen shot of screen

1
  • 2
    if you share your code in stackbitz.com it will be easy to help Commented Jul 5, 2018 at 16:46

2 Answers 2

4

You should be using the same formGroup in parent as well as child component. You can pass the parent formGroup as an input to child component.

Before that create @Input() property in child component

component A

export class DatabaseServerComponent implements OnInit {
  @Input() dbForm : FormGroup;

  constructor(private fb: FormBuilder) {
    this.createForm();
  }
  createForm() {
   // Simply add child control to the form. No need to create form again
   this.dbForm.addControl('dbServer', new FormControl('', Validators.required));
  }

Now pass parent form newPfForm to child as an input, so that they share the same form group

template B (parent)

<div>
    <app-database-server [dbForm]="newPfForm"></app-database-server>
</div>

Template of component A would remain as it is. No Change.

Sign up to request clarification or add additional context in comments.

4 Comments

You would also need to add new form controls in Component A under a div which has formGroup directive. In continuation to above, html of Component A would look like <div [formGroup]="dbForm"> ....YOUR FORM CONTROL HTML </div> Else you will get Error: formControlName must be used with a parent formGroup directive
@Avij OP's child component (Component A) already has the same structure what you are mentioning here.
Ooops...Dint notice that. Looked your answer only.
You may try this this.dbForm.addControl('dbServer', new FormControl('', Validators.required)); Updated the answer with that.
1

In order to sync the values of nested form components, you need to set the formGroupName parameter:

https://angular.io/api/forms/FormGroupName

1 Comment

Can you point me to a live example as I have followed the link but I am not able to make it work in my case?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.