35

How can I set the default value for all forms fields in angular 2 reactive forms?

Here is the plnkr to reproduce the issue

Below code does not update dropdown values as it has an object associated with it.

Note: Here I need to set the default value for all form fields with the response received from Backend API.

Component.html

<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm.value, myForm.valid)">
    <div class="form-group">
        <label>Country:</label>
        <select formControlName="country">
          <option *ngFor="let country of masterCountries" [ngValue]="country">{{country.countryName}}</option>
        </select>
    </div>

    <div class="form-group">
      <label for="">Name</label>
      <input type="text" class="form-control" formControlName="name">
      <small [hidden]="myForm.controls.name.valid || (myForm.controls.name.pristine && !submitted)" class="text-danger">
            Name is required (minimum 5 characters).
          </small>
      <!--<pre class="margin-20">{{ myForm.controls.name.errors | json }}</pre>-->
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
    <div class="margin-20">
      <div>myForm details:-</div>
      <pre>Is myForm valid?: <br>{{myForm.valid | json}}</pre>
      <pre>Is myForm submitted?: <br>{{submitted | json}}</pre>
      <pre>myForm value: <br>{{myForm.value | json}}</pre>
    </div>

Component.ts

export class AppComponent implements OnInit {
    public myForm: FormGroup;
    public masterCountries: any[] = [{"countryCode":"AF","countryName":"Afghanistan"},{"countryCode":"AL","countryName":"Albania"},{"countryCode":"DZ","countryName":"Algeria"},{"countryCode":"AS","countryName":"American Samoa"},{"countryCode":"AD","countryName":"Andorra"}];

    // Sample response received from backend api
    public CountryResponse = {country: {"countryCode":"AF","countryName":"Afghanistan"}, name: 'test123'};
    constructor(private _fb: FormBuilder) { }

    ngOnInit() {

        // the short way
        this.myForm = this._fb.group({
            country: [''],
            name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
        });


        (<FormGroup>this.myForm)
            .setValue(this.CountryResponse, {onlySelf: true});


    }


    save(model: User, isValid: boolean) {
        this.submitted = true;
        console.log(model, isValid);
    }
}

Let me know if there is any other way to set the whole form.

3

4 Answers 4

50

I know this is an old question, but if anyone looks for it, there is now a better way to set value in the whole form, with PatchValue:

this.myForm.patchValue({
   country: this.CountryResponse,
   name: 'Any Name'
});

this also allows partial, so you would still be able to do something like:

this.myForm.patchValue({ country: this.CountryResponse });

or you can set the value into a single control:

this.myForm.get('country').setValue(this.CountryResponse);
Sign up to request clarification or add additional context in comments.

Comments

17

When you declare the form control or initialise pass the default value as a parameter

  MyFormControl: FormControl = new FormControl('Default value');

3 Comments

cleanest way to do this
I think this is a cleaner way to achieve. It worked for me thanks
What if I dont want to show default value in HTML view?
13

Just change this:

 (<FormGroup>this.myForm)
            .setValue(this.CountryResponse, {onlySelf: true});

Into this:

const selectedCountry = this.masterCountries.find(country => country.countryCode === this.CountryResponse.country.countryCode)
this.CountryResponse.country = selectedCountry;
(<FormGroup>this.myForm)
            .setValue(this.CountryResponse, {onlySelf: true});

As said before you need to pass the exact same reference of the object

1 Comment

patchValue is more appropriate
10

Your code does not work because although your this.selectedCountry appears to have the same fields' values with one of the elements of this.masterCountries, they are not the same object. That makes select.value === option.value comparison always returns false.

It's simple to make it works, just change your setValue function to as follow:

(<FormControl>this.form.controls['country'])
            .setValue(this.masterCountries[0], { onlySelf: true });

Or you can just set it when creating the FormGroup:

    this.myForm = this._fb.group({
        country: [this.masterCountries[0]],
        name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
    });

1 Comment

Thanks for the answer. Yes it works if i use the masterCountries to set the value. But I need to set the whole form with the response received from backend. Updated my plnkr with thsi scenario. plnkr.co/edit/GKguMzZbr0kzrraPP73f?p=preview

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.