javascriptangulartypescriptangular-reactive-formsangular10

Angular reactive forms patchValue or setValue not working - Angular 10


I am using Reactive forms, everything's good but when I am patching values, they are not updated. I tried patchValue and setValue as well, but nothing seems to work. Below is my code

    ngOnInit(){
    this.profileForm = this.fb.group({
          'name': ['', Validators.required],
          'email': ['', [Validators.required, Validators.email]],
          'phNumber': ['', Validators.required],
          'gender': ['', Validators.required],
          'address': ['', Validators.required],
          'city': ['', Validators.required],
          'state': ['', Validators.required],
          'pincode': ['', Validators.required]
        });
    }

Patching value

    let response = res['expert'];
          this.profileForm.setValue({
            name: response.full_name,
            email: response.expert_email,
            phNumber: response.expert_mobile,
            address: response.addresss,
            city: response.city,
            state: response.state,
            pincode: response.pincode,
            gender: response.id_gender
          });

getting this error if I use setValue

enter image description here

Form values are getting set if I use patchValue,

    after = {"name":"Test Name","email":"testa@gmail.com","phNumber":"9632587410","gender":1,"city":"Adilabad","state":"ANDHRA PRADESH","pincode":"2352"}

    <section class="marginBoxModelForProfile">
        <form [formGroup]="profileForm">
            <h6 class="text-left circularBold"><b>Complete Profile Details</b></h6>
            <p class="text-left circularBold grey5F font-size14">Min 300 Rs. Explanation about how they can choose and
                why they should choose the right fields. A link and details on how to join will be included in your
                booking confirmation email.</p>
            <input type="text" class="education-inputs w-100 mt-3" placeholder="Name" formControlName="name"
                [ngClass]="{'input-error': submitted && profileForm.controls.name.invalid}">
            <div class="mt-3 text-left">
                <!-- <ng-container *ngFor="let gender of genders">
                    <input type="radio" name="gender" id="gender" class="mr-1" value="">
                    <span class="mr-5" formControlName="gender">
                        {{gender.gender_name}}
                    </span>
                </ng-container> -->
                <input type="radio" name="gender" id="gender" class="mr-1" [value]="1" (change)="onChangeGender($event)"> <span class="mr-5"
                    formControlName="gender">Male</span>
                <input type="radio" name="gender" id="gender" class="mr-1" [value]="2" (change)="onChangeGender($event)"> <span class="mr-5"
                    formControlName="gender">Female</span>
                <input type="radio" name="gender" id="gender" class="mr-1" [value]="3" (change)="onChangeGender($event)"> <span class="mr-5"
                    formControlName="gender">Other</span>
            </div>
            <div class="input-group mt-3">
                <div class="input-group-prepend">
                    <span class="input-group-text contactNumber-addon" id="basic-addon1"
                    [ngClass]="{'input-error': submitted && profileForm.controls.phNumber.invalid}">+91</span>
                </div>
                <input type="text" class="form-control contactnumber-input" placeholder="Contact Number"
                    aria-label="contactNumber" aria-describedby="basic-addon1" formControlName="phNumber"
                    [ngClass]="{'input-error': submitted && profileForm.controls.phNumber.invalid}">
            </div>
            <input type="email" class="education-inputs w-100 mt-3" placeholder="Email" formControlName="email"
                [ngClass]="{'input-error': submitted && profileForm.controls.email.invalid}">
            <input type="text" class="education-inputs w-100 mt-3" placeholder="Address" formControlName="address"
                [ngClass]="{'input-error': submitted && profileForm.controls.address.invalid}">
            <p class="font-size12 grey8E circularBook text-left mt-2">We use this detail to generate invoices and use it
                for tax purposes.</p>
            <div>
                <input type="text" class="education-inputs w-100 mt-3" placeholder="Pincode" formControlName="pincode"
                    [ngClass]="{'input-error': submitted && profileForm.controls.pincode.invalid}"
                    (change)="onChangePincode($event)">
            </div>
            <div class="text-left">
                <select name="city" id="city" class="education-inputs mt-3 mr-1 w-50" formControlName="city"
                    [ngClass]="{'input-error': submitted && profileForm.controls.city.invalid}">
                    <option value="{{city}}">{{city}}</option>
                </select>
                <select name="state" id="state" class="education-inputs mt-3 state-dropdown" formControlName="state"
                    [ngClass]="{'input-error': submitted && profileForm.controls.state.invalid}">
                    <option value="{{state}}">{{state}}</option>
                </select>
            </div>
            </div>
        </form>
    </section>

enter image description here

I have used patchValue also, please help what I'm doing wrong. I am using v10.

Any help is much appreciated.

Thanks in advance!


Solution

  • First Error

    The problem is that the value of response.address is undefined

    As you have stated you can simply use patchValue() to set all the defined values and that should work fine

    If you need to use setValue for any reason then you can change the line address: response.address, to

     address: response.address ?? '',
    

    We are simply checking if the value of address exists and if not set it to ''

    Second Error

    Consider below code

     <input type="radio" name="gender" id="gender" class="mr-1" value="">
        <span class="mr-5" formControlName="gender">{{gender.gender_name}}</span>
    

    As the error states span element does not have a ValueAccessor Just move the formControlName="gender" attribute to the input tag

     <input  formControlName="gender" type="radio" id="gender" class="mr-1" [value]="gender.value">
        <span class="mr-5">{{gender.gender_name}}</span>
    

    See this Solution

    Third non-error issue

    I see you using the following:

    (change)="onChangePincode($event)"
    

    You can subscribe to the form if you're using reactive forms and handle this without using (change) directly in the html. It has a formControlName, so i f you subscribe to the form changes, you can do away with this in your html.