1

I am just a newbie to angular. I have create a event component where user enters the event name with packages. When user creates an event it has the functionality for creating multiple packages with add and remove row. For that I have used FormArray.

Everything is fine here. But when I am trying to get those values in event edit component I am getting the value of event name but when I am trying to get the packages details I am little bit confused in showing rows with filled values.

Here is the code what I have done so far

event-edit.component .ts looks like this

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

import { FormControlName } from '@angular/forms/src/directives/reactive_directives/form_control_name';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { EventService } from '../event.service';


@Component({
  selector: 'app-event-edit',
  templateUrl: './event-edit.component.html',
  styleUrls: ['./event-edit.component.css']
})
export class EventEditComponent implements OnInit {

  event = {};


  constructor(
    private http: HttpClient,
    private router: Router,
    private route: ActivatedRoute,
    private formBuilder : FormBuilder,
    private eventService : EventService,
    ) { this.createEventForm(); }

  createEventForm() {
    this.form = this.formBuilder.group({
      eventname: ['', Validators.compose([
        Validators.required,
        Validators.minLength(5)
      ])],
    })
  }

  ngOnInit() {
    this.getOneEvent(this.route.snapshot.params['id']);
    this.form = new FormGroup({
      eventname: new FormControl('', [ Validators.required, Validators.minLength(5)]),
      sections: new FormArray([
        this.initSection(),
      ]),
    });
  }

  getOneEvent(id) {
    this.http.get( this.domain + '/api/event/' + id).subscribe(data => {
      this.event = data['eventname'];
      this.packages = data['packages']; //getting packages as array object
    });

  }

  public addPackageRow() {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection());
  }

  addSection() {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection());
  }

  initSection() {
    return new FormGroup({
      packagename: new FormControl('', [ Validators.required, Validators.minLength(5)]),
      packageprice: new FormControl(''),
      packagelimit: new FormControl('')
    });
  }

  getSections(form) {
    return form.controls.sections.controls;
  }

  public removeSection(i){
    const control = <FormArray>this.form.get('sections');
     control.removeAt(i);
  }

}

event-edit.component.html looks like this

<div class="container col-md-10">
  <h1 class="page-header">Event Edit</h1>
  <!-- <div class="row show-hide-message">
    <div [ngClass]= "messageClass">{{message}}</div>
  </div> -->
  <form [formGroup] = "form" (ngSubmit)="updateEvent(event._id)">
    <fieldset>
      <div class="form-group">
        <label for="eventname">Event Name</label>
        <div class='form-group'>
          <input type="text" formControlName="eventname" class="form-control" autocomplete="off" [(ngModel)]="eventname" placeholder="Event Name" >
        </div>
      </div>


      <h4>Package Price</h4>
      <hr>
      <div class="row" formArrayName="sections">
        <div class="col-md-12" *ngFor="let section of getSections(form); let i = index" [formGroupName]="i">

        <div class="form-group col-md-5">
          <label for="packagename">Package Name</label>
          <input type="text" class="form-control" autocomplete="off" placeholder="Package Name" formControlName="packagename">
       </div>
        <div class="form-group col-md-2">
          <label for="packageprice">Package Price</label>
          <input type="number" class="form-control" autocomplete="off" placeholder="Package Price" formControlName="packageprice" >
        </div>
        <div class="form-group col-md-3">
          <label for="packagelimit">Max Purchase Limit</label>
          <input type="number" class="form-control" formControlName="packagelimit" autocomplete="off" >
        </div>
        <div class="form-group col-md-1">
          <br/>
          <input type="button" (click)="addPackageRow()" class="btn btn-md btn-success" value="+" name="">
        </div>
        <div class="form-group col-md-1" *ngIf="getSections(form).length > 1">
          <br/>
          <input type="button" (click)="removeSection(i)" class="btn btn-md btn-error" value="-" name="">
        </div>
      </div>
      </div>
      <input type="submit" class="btn btn-primary" value="Update">
    </fieldset>
  </form>
</div>
5
  • What is the output when you select an event? Commented Feb 15, 2018 at 10:05
  • I am getting those values from database but I am confused in showing the data of formarray Commented Feb 15, 2018 at 10:07
  • I have angular project that I used reactive-forms to create nested forms in gitlab. More exactly: Question form with multiple answers. I can invite you, you can run and check it in your computer Commented Feb 15, 2018 at 10:10
  • Okay. Please share the link or share some code. So that I can have a look in it. Commented Feb 15, 2018 at 10:13
  • repl, online demo in firebase Commented Feb 15, 2018 at 10:19

1 Answer 1

1

You will have to just loop through data in packages and add it to form.

After your service you will intialize the loop :-

 getOneEvent(id) {
    this.http.get( this.domain + '/api/event/' + id).subscribe(data => {
      this.event = data['eventname'];
      this.packages = data['packages']; //getting packages as array object
      for(let package of this.packages){
        this.addSection(package)
      }
    });

  }

then in your sections function you will pass the same to initSection.

addSection(package) {
    const control = <FormArray>this.form.get('sections');
    control.push(this.initSection(package));
  }

then finally in your initSection You will assign values

initSection(package) {
      if (!package) {
        var package = {
          packagename : "",
          packageprice : "",
          packagelimit : ""
        }
      }
      return new FormGroup({
        packagename: new FormControl(package.packagename, [Validators.required, Validators.minLength(5)]),
        packageprice: new FormControl(package.packageprice),
        packagelimit: new FormControl(package.packagelimit)
      });
    }

The if condition is for when you add a blank (a new ) item.

Also remove the call of addSection from ngOnInit else first row will be left empty.

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

5 Comments

seems like its working but the thing is it is showing the first row as empty. From 2nd row it is actually populating data.
remove the call of addSection form ngOnInit
I have only used sections: new FormArray([ this.initSection(''), ]), in ngOnit . because without it shows error like Cannot read property 'push' of null
can you help me in my other question stackoverflow.com/questions/48865663/…
can you answer my another question? Here it is stackoverflow.com/questions/48946695/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.