Search code examples
angularangular-reactive-formsangular-forms

FormGroup.value returns the default value not the updated ones


I have a small form and on click of a button I want to access the latest values of the form. But what I get is the default values with which I initialized the form.

I am using material for designing the input fields

component.ts

import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ElementService } from 'src/app/services/element.service';

import { PeriodicElement } from '../../../Interfaces/periodicElement';

@Component({
    selector: 'app-create',
    templateUrl: './create.component.html',
    styleUrls: ['./create.component.css']
})

export class CreateComponent {

    formGroup: FormGroup;
    inProgress: boolean = false;
    onChange = (_: any) => { };

    constructor(
        private elementService: ElementService,
        private formBuilder: FormBuilder,
        public dialogRef: MatDialogRef<CreateComponent>,
        @Inject(MAT_DIALOG_DATA) public data: PeriodicElement
    ) {
        this.formGroup = this.formBuilder.group({
            position: [this.data.position, Validators.required],
            name: [this.data.name, Validators.required],
            weight: [this.data.weight, Validators.required],
            symbol: [this.data.symbol, Validators.required]
        });
    }

    valueChanges(controlGroup: string) {
        let value = this.formGroup.get(controlGroup)?.value;
        this.onChange(value);
    }

    save() {
        console.log(this.formGroup.value)
        this.inProgress = true;
        this.elementService.list().subscribe(list => {
            this.inProgress = false;
            this.dialogRef.close(list);
        });

    }
}

Component.html

<h1 mat-dialog-title>Add Element</h1>
<mat-dialog-content>
    <form [formGroup]="formGroup">
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Position</mat-label>
            <input matInput type="number" [value]="data.position" (valueChanges)="valueChanges('position')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Name</mat-label>
            <input matInput [value]="data.name" (valueChanges)="valueChanges('name')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Weight</mat-label>
            <input matInput type="number" [value]="data.weight" step=".00001" (valueChanges)="valueChanges('weight')" />
        </mat-form-field>
        <mat-form-field appearance="fill" class="spacer">
            <mat-label>Symbol</mat-label>
            <input matInput [value]="data.symbol" (valueChanges)="valueChanges('symbol')" />
        </mat-form-field>
    </form>
</mat-dialog-content>
<mat-dialog-actions align=end>
    <mat-spinner [diameter]="20" *ngIf="inProgress"></mat-spinner>
    <button color="accent" mat-raised-button (click)="save()">Add</button>
    <button color="warn" mat-raised-button mat-dialog-close>Cancel</button>
</mat-dialog-actions>

Solution

  • Modify the component.html to -

    <h1 mat-dialog-title>Add Element</h1>
    <mat-dialog-content>
        <form [formGroup]="formGroup">
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Position</mat-label>
                <input matInput type="number" formControlName="position" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Name</mat-label>
                <input matInput formControlName="name" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Weight</mat-label>
                <input matInput type="number" step=".00001" formControlName="weight" />
            </mat-form-field>
            <mat-form-field appearance="fill" class="spacer">
                <mat-label>Symbol</mat-label>
                <input matInput formControlName="symbol" />
            </mat-form-field>
        </form>
    </mat-dialog-content>
    <mat-dialog-actions align=end>
        <button color="accent" mat-raised-button (click)="save()">Add</button>
        <button color="warn" mat-raised-button mat-dialog-close>Cancel</button>
    </mat-dialog-actions>
    

    and you don't need the onChange property and the valueChanges() method in the component.ts anymore.