0
votes

I have an parent component and I have a child component. My child component has a reactive form. I would like to capture some input from the child form and submit it. However, whenever the form is inside a child component (as opposed to just being inside a parent), the submit function does a postback. The same exact component works fine if it is standalone and not a child to another component. I'm somewhat new to angular so I feel like there is some standard way of accomplishing this that I'm not aware of.

My project is an angular ionic project, but that should have nothing to do with it. Also, I was initially trying to use this child component (AdditemComponent) as an ionic modal and I was experiencing the same exact issue where the form post was doing a postback to the querystring instead of just calling the onSave method.

My goal is to capture the data in the child component and process and submit the data in the child component. This would allow me to just drop it wherever I need it.

Parent.ts:

import { Component, OnInit, Input } from '@angular/core';
import { AdditemComponent } from 'src/app/competitions/additem/additem.component'

@Component({
  selector: 'app-settings',
  templateUrl: './settings.page.html',
  styleUrls: ['./settings.page.scss'],
})
export class SettingsPage implements OnInit {

  constructor(){ }

  ngOnInit(){ }

}

Parent.html

<ion-header>
  <ion-toolbar>
    <ion-title class="ion-text-center">Settings</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <app-additem></app-additem>  
</ion-content>

Child.ts

import { Component, OnInit, Input } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { FormGroup, FormBuilder } from '@angular/forms';


@Component({
  selector: 'app-additem',
  templateUrl: './additem.component.html',
  styleUrls: ['./additem.component.scss'],
})
export class AddplayerComponent implements OnInit {

  @Input() selectedResult;
  private newItemForm : FormGroup;
  private teams:[];

  constructor(
    private modalCtrl: ModalController,
    private formBuilder: FormBuilder,
    private dataservice
  ) { 
    this.newItemForm = this.formBuilder.group({
      fname: [''],
      lname: [''],
      shortname: [''],
      team: ['']
    })
  }


  ngOnInit() {
  }

  onSave() {
    console.log('captured form data', this.newItemForm);
  }

  onCancel() {
    this.modalCtrl.dismiss(null, 'cancel');
  }

}

Child.html

<ion-item class="header">
  <p>Add New Item</p>
</ion-item>

<form [formGroup]="newItemForm" (ngSubmit)="onSave()">
  <ion-item>
    <ion-label>First Name</ion-label>
    <ion-input type="text" formControlName="fname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Last Name</ion-label>
    <ion-input formControlName="lname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Short Name</ion-label>
    <ion-input formControlName="shortname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Team</ion-label>
    <ion-select formControlName="item">
      <ion-item *ngFor="let item of items">
        <ion-select-option [value]="item.itemId">{{item.itemName}}</ion-select-option>
      </ion-item>
    </ion-select>
  </ion-item>
  <ion-item>
    <ion-button color="primary" type="submit" [disabled]="!newItemForm.valid">Submit</ion-button>
    <ion-button color="danger" (click)="onCancel()">Cancel</ion-button>
  </ion-item>
</form>
1

1 Answers

1
votes

Try like this

parent.component.html

 <app-child (onsave)="saveInParent($event)"></app-child>

parent.component.ts

saveInParent(event) {
   console.log(event);
}

child.component.html

<div style="margin: 10px 20px;">
  <form [formGroup]="childForm">
    <input type="text" formControlName="email" placeholder="email"/>
    <div class="error" *ngIf="childForm.controls['email'].hasError('required') && childForm.controls['email'].touched">Email required.</div>
    <div class="error" *ngIf="childForm.controls['email'].hasError('required') && isSubmited">Email required.</div>
    <br/>
    <br/>
    <input type="password" formControlName="password" placeholder="password"/>
    <div class="error" *ngIf="childForm.controls['password'].hasError('required') && childForm.controls['password'].touched">Password required.</div>
    <div class="error" *ngIf="childForm.controls['password'].hasError('required') && isSubmited">Password required.</div>
    <br/>
    <br/>
    <button (click)="save()">Save</button>
</form>

child.component.ts

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  isSubmited = false;
  childForm: FormGroup;
  constructor(private fb: FormBuilder) { }
  @Output() public onsave = new EventEmitter();
  ngOnInit() {
    this.initForm();
  }
  initForm(){
    this.childForm = this.fb.group({
      email: ['', [Validators.required]],
      password: ['', [Validators.required]],
    });
  }
  save() {
    this.isSubmited = true;
    if (this.childForm.valid) {
      this.onsave.emit(this.childForm.value);
    }
  }

}