Search code examples
angularangular4-forms

Angular 4, Fetch Form Data, Edit and Upload



I'm trying to learn Angular 4. Learning by doing.

What I'm trying to do is,
1. Get data from server in json form. [done]
2. Populate it into forms. [with some issues]
3. Let the user make changes to those data [done]
4. Send the new data as json to the server.[problem: cant get the data from form]

Issue I'm facing is, when I try to submit the form, I'm not getting that data from the form. Any help is appreciated.
My template file

<div *ngIf="!name; else forminfo">
  <form [formGroup]="rForm" (ngSubmit)="addPost(rForm.value)">
    <div class="form-container">
        <h1>Enter Details</h1>
      <div class="row columns" *ngFor="let item of data;let i=index;" >
<div formArrayName="add">
        <label>ID
          <input type="text" formControlName="id" value="{{item.id}}">
        </label>

        <label>Deposit
          <input type="text" formControlName="deposit" value="{{item.deposit}}">
        </label>


        <label>Year
          <input type="text" formControlName="year" value="{{item.year}}">
        </label>

        <label>Maturity
          <input type="text" formControlName="maturity" value="{{item.maturity}}">
        </label>

      </div>

      </div>
      <!-- [disabled]="!rForm.valid" -->
      <input type="submit" class="button expanded" value="Submit Form" >
    </div>
  </form>
</div>

<ng-template #forminfo>
  <div class="form-container">
    <div class="row columns">
        <h1>{{ name }}</h1>

        <p>{{ description }}</p>
    </div>
  </div>
</ng-template>

Component File:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import {Http,Response} from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  rForm: FormGroup;
 data:any;
  constructor(private fb: FormBuilder,private http: Http) {
    this.rForm = fb.group({

      add: this.fb.array([
        this.fb.group({
          id: [''],
          deposit: [''],
          year: [''],
          maturity: [''],
      })
    ]),

    });
  }


  ngOnInit() {
    this.http.get('http://svcsociety.com/json/yojna.txt').map((res: Response) => 
    res.json()).subscribe(res => {
                               this.data = res;
                               //console.log(JSON.stringify(this.data));
                               });

  }

  addPost(post) {
    alert(JSON.stringify(post));
  }

}

Here is how JSON looks like

[
{"id":"1", "deposit": "Rs 50,000","year":"18","maturity":"Rs 4,00,000"},
{"id":"2", "deposit": "Rs 1,00,000","year":"18","maturity":"Rs 8,00,000"},
{"id":"3", "deposit": "Rs 1,50,000","year":"18","maturity":"Rs 12,00,000"},
{"id":"4", "deposit": "Rs 2,00,000","year":"18","maturity":"Rs 16,00,000"},
{"id":"5", "deposit": "Rs 250000","year":"18","maturity":"Rs 20,00,000"},
{"id":"6", "deposit": "Rs 300000","year":"18","maturity":"Rs 24,00,000"}
]

Solution

  • Use the formArray, insert the values to it and then iterate the formarray in your template instead of data. So when you receive your data, iterate it and insert the values to your formarray add:

    let formArr = this.rForm.controls.add as FormArray;
    this.data.forEach(x => {
      formArr.push(this.fb.group({
        id: x.id,
        deposit: x.deposit,
        year: x.year,
        maturity: x.maturity
      }))
    })
    

    Then as mentioned, iterate that formarray in your template and just use formControlName instead of value:

    <form [formGroup]="rForm" (ngSubmit)="addPost(rForm.value)">
      <div formArrayName="add">
        <div *ngFor="let dat of this.rForm.controls.add.controls; index as i" [formGroupName]="i">
          <input formControlName="id" />
          <input formControlName="deposit" />
          <input formControlName="year" />
          <input formControlName="maturity" />
        </div>
      </div>
      <input type="submit" class="button expanded" value="Submit Form" >
    </form>
    

    and there is no need to insert the initial formgroup to the form array, you can just set it as empty:

    this.rForm = fb.group({
      add: this.fb.array([]),
    });
    

    DEMO: https://stackblitz.com/edit/angular-yxhprn?file=app%2Fapp.component.ts