user1238784
user1238784

Reputation: 2440

Angular reactive Form error: Must supply a value for form control with name:

I premise I am very novice with Angular. I am trying to implement an Angular reactive form, but I am encountering this error: "Must supply a value for form control with name: Destination.

This is the relevant parts of my component and my html:

import { Component, Inject } from '@angular/core';
import { Http } from "@angular/http";
import { FormGroup, FormControl, FormBuilder, Validators } from "@angular/forms";

@Component({
    selector: 'home',
    templateUrl: './home.component.html'
})
export class HomeComponent {

    locations: Location[];
    flightChoice: FlightChoice;
    form: FormGroup;
    

    constructor(http: Http, @Inject('BASE_URL') private baseUrl: string,
        private fb: FormBuilder) {

        this.createForm();

        http.get(baseUrl + 'api/FlightChoice/dest_locations').subscribe(result => {
            this.locations = result.json() as Location[];
            console.log(this.locations);
                        
        }, error => console.error(error));
       
        http.get(baseUrl + 'api/FlightChoice/choice').subscribe(result => {
            this.flightChoice = result.json() as FlightChoice;
            this.updateForm();
        }, error => console.error(error));
      
    }

    createForm() {
        this.form = this.fb.group({
            Destination: [0],
            NrPasg: [1],
            TwoWays: [false],
            DepartureDate: ['', Validators.required],
            ReturnDate: ['', Validators.required]
        });
    }

    updateForm() {

        this.form.setValue({
            Destination: this.flightChoice.DestinationId,
            NrPasg: this.flightChoice.NrPasg,
            TwoWays: this.flightChoice.TwoWays,
            DepartureDate: this.flightChoice.DepartureDate,
            ReturnDate: this.flightChoice.ReturnDate
        });

    }

html:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
        <div>
            <label for="destination">Destination:</label>
            <br />
            <select id="destination" formControlName="Destination">
                <option *ngFor="let location of locations" value="{{ location.id }}">
                    {{ location.name }}
                </option>
            </select>
            <br />
            <label for="nrPasg">Number of Passengers:</label>
            <br />
            <input formControlName="NrPasg" type="number" id="nrPasg" value="1" />
            <label for="twoWays"></label>
            <br />
            <select id="twoWays" formControlName="TwoWays">
                <option value="false">one way</option>
                <option value="true">two ways</option>
            </select>
            <br />
            <label for="departureDate">Departure Date:</label>
            <br />
            <input formControlName="DepartureDate" type="date" id="departureDate" />
            <br />
            <label for="returnDate">Return Date:</label>
            <br />
            <input formControlName="ReturnDate" type="date" id="returnDate" />

        </div>
        <div>
            <button type="submit">Search Flights</button>
           
        </div>
    </form>

I know I am probably writing something wrong in the createForm method but I am not sure how to assign the values

Upvotes: 89

Views: 137587

Answers (4)

Simon_Weaver
Simon_Weaver

Reputation: 146188

Unfortunately undefined isn't allowed, you need to set each property to null.

You can convert properties before calling setValue with something like this:

   // set all 'missing' OR 'undefined' properties to null
   const newValue: any = {...value};

   for (const field in this.controls) { 

       if (newValue[field] === undefined) {
           newValue[field] = null;
       }
   }

   super.setValue(newValue, options);

Watch out because JSON.stringify() will remove undefined, and so if you use that to send a value back to your server you need to make sure it can handle missing properties there.


Alternative way, and this is more of a Javascript tip than anything:

You can use ?? when setting properties to ensure they're null. This may help in some cases.

eg.

form.setValue({

   firstName: firstName ?? null,    // null if firstName === undefined
   lastName: lastName ?? null

})

This is favorable to using || since a numeric form value (and a form value can be any type) of 0 would get wiped out by this. (Since 0 || null => null and not 0).

Upvotes: 22

davood beheshti
davood beheshti

Reputation: 970

I had the same problem For example, the model that I was building to the form, some of the form items were not in that model and that's why I faced this problem.

For example, my form is like this

this.form = new FormGroup({
   name: new FormControl(),
   family : new FormControl(),
   age: new FormControl(),
   email : new FormControl()
})

The model I was building was like this

 const model = {
   name : 'davod',
   family : 'beheshti',
   age : "23"
 }

 this.form.setValue({...model})

And this error happened to me about email

By adding email to the model, my problem was completely solved

Upvotes: 0

adamdport
adamdport

Reputation: 12633

This error can appear if you're using setValue on a formGroup but not passing in a value for every control within that group. For example:

let group = new FormGroup({
  foo: new FormControl(''), 
  bar: new FormControl('')
});
group.setValue({foo: 'only foo'}); //breaks
group.setValue({foo: 'foo', bar: 'bar'}); //works

If you truly want to only update some of the controls on the group, you can use patchValue instead:

group.patchValue({foo: 'only foo, no problem!'});

Docs for setValue and patchValue here

Upvotes: 171

ambussh
ambussh

Reputation: 790

Probably the error appears because this.flightChoice.DestinationId === undefined and you try to set undefined to the Destination field on the form.

Check if api is correctly downloading data to this.flightChoice.

Upvotes: 13

Related Questions