user1531921
user1531921

Reputation: 1432

angular reactive form throws "Cannot find control with name" for irrelevant model field

I'm attempting to build an edit component with Angular Reactive forms. However, I get the error "Error: Cannot find form control with name: created.", with "created" being a property on my model.

However, created is not an editable field and should not be bound to the form. I don't specify it in my form builder nor is there a control on my edit.html page. It is only present on my model. How do I tell form validator to ignore this and other irrelevant model properties?

Here's my model:

        export class User {
      id: number;
      userName: string;
      password: string;
      passwordHash: string;
      lastName: string;
      firstName: string;
      email: string;
      created: string;
      lastLogin: string;
      description: string;
      isSaved: boolean;
      passsword:string;
      passwordConfirm:string;
    }

Here's my component:

    import { Component, OnInit, Inject } from '@angular/core';
import { Router } from "@angular/router";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { first } from "rxjs/operators";
import { User } from "../../model/user.model";
import { UserService } from "../../service/user.service";


@Component({
  selector: 'app-edit-user',
  templateUrl: './edit-user.component.html',
  styleUrls: ['./edit-user.component.css']
})
export class EditUserComponent implements OnInit {

  user: User;
  editForm: FormGroup;

  constructor(private formBuilder: FormBuilder, private router: Router, private userService: UserService) { }

  ngOnInit() {
    let userId = window.localStorage.getItem("editUserId");
    if (!userId) {
      alert("Invalid action.")
      this.router.navigate(['list-user']);
      return;
    }
    this.editForm = this.formBuilder.group({
      id: [''],
      userName: ['', Validators.required],
      password: ['', Validators.required],
      passwordConfirm: ['', Validators.required],
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      email: ['', Validators.email],
      description: [''],
    });
    this.userService.getUserById(+userId)
      .subscribe(data => {
        this.editForm.setValue(data);
      });
  }

  onSubmit() {

    if(!this.editForm.value.passwordConfirm){
      console.log("password confirmed is undefined. Setting");
      this.editForm.value.passwordConfirm = this.editForm.value.password;
    }

    this.userService.updateUser(this.editForm.value)
      .pipe(first())
      .subscribe(
        data => {
          alert('User updated successfully.');
          this.router.navigate(['list-user']);
        },
        error => {
          alert("En error occured and changes should not be saved. Details: " + error);
        });
  }
}

Here's my html:

        <div class="col-md-6 user-container">
          <h2 class="text-center">Edit User</h2>
          <form [formGroup]="editForm" (ngSubmit)="onSubmit()">

            <div class="hidden" style="display:none;">
              <input type="text" formControlName="id" placeholder="id" name="id" class="form-control" id="id">
            </div>

            <!-- todo: replace display none with bootstrap class -->

            <div class="form-group" style="display:none;">
              <input type="text" formControlName="userName" placeholder="userName" name="userName" class="form-control"
                id="userName" readonly="true">
            </div>

            <div class="form-group">
              <label for="firstName">First Name:</label>
              <input formControlName="firstName" placeholder="First Name" name="firstName" class="form-control" id="firstName">
            </div>

            <div class="form-group">
              <label for="lastName">Last Name:</label>
              <input formControlName="lastName" placeholder="Last name" name="lastName" class="form-control" id="lastName">
            </div>

            <div class="form-group">
              <label for="email">Email:</label>
              <input formControlName="email" placeholder="email" name="email" class="form-control" id="email">
            </div>

            <div class="form-group">
              <label for="description">Description:</label>
              <input formControlName="description" placeholder="Description" name="description" class="form-control"
                id="description">
            </div>

            <hr>

            <h5>Change password</h5>

            <div class="form-group">
              <label for="password">New password:</label>
              <input type="password" formControlName="password" placeholder="password" name="password" class="form-control"
                id="password">
            </div>

            <div class="form-group">
              <label for="passwordConfirm">Confirm password:</label>
              <input type="password" formControlName="passwordConfirm" placeholder="passwordConfirm" name="passwordConfirm"
                class="form-control" id="passwordConfirm">
            </div>

            <button class="btn btn-success">Update</button>
          </form>
        </div>

Here's the error details:

Error: Cannot find form control with name: created. core.js:5847 message:"Cannot find form control with name: created." stack:"Error: Cannot find form control with name: created.\n at FormGroup._throwIfControlMissing (https://localhost:5001/vendor.js:70056:19)\n at https://localhost:5001/vendor.js:69913:19\n at Array.forEach ()\n at FormGroup.setValue (https://localhost:5001/vendor.js:69912:28)\n at SafeSubscriber._next (https://localhost:5001/main.js:1937:28)\n at SafeSubscriber.__tryOrUnsub (https://localhost:5001/vendor.js:95425:16)\n at SafeSubscriber.next (https://localhost:5001/vendor.js:95363:22)\n at Subscriber._next (https://localhost:5001/vendor.js:95309:26)\n at Subscriber.next (https://localhost:5001/vendor.js:95286:18)\n at MapSubscriber._next (https://localhost:5001/vendor.js:100330:26)"

Upvotes: 3

Views: 13085

Answers (2)

Vikas Keskar
Vikas Keskar

Reputation: 1248

Angular reactive forms accepts only those values which are present in form builder, if you have some extra properties in the object, you are using to set values, it gives error for that property. Here, you have created as extra, if you solved somehow that error, it will again give error to lastLoginas it is not part of form builder.

this.userService.getUserById(+userId)
  .subscribe(data => {
   const propertyToSelect = ['id','userName', 'password','passwordConfirm', 'firstName', 'lastName','email', 'description']
   const objectToSetValue = propertyToSelect.map((property) => {property: data[property]})
   this.editForm.setValue(objectToSetValue);
  });

Upvotes: 2

Alex Biro
Alex Biro

Reputation: 1237

It seems like that you want to set a User object into the form, which doesn't have a control called created.

You either remove that field from the object that you pass to setValue, or instead of setValue use patchValue, which seems to ignore unknown fields, and also, only touches those controls, which are specified in the object passed in and leaves the other controls alone, as opposed to setValue, which reset those controls, which are not specified in the object passed in.

Upvotes: 8

Related Questions