angulartypescriptformbuilder

Set user value from service data to FormGroup


For my Angular Project I have a user profile and i want to put values of user in Form control. I've tried many things but in don't have the result I want I want to set values of User dynamically from my service

Here's my form.html

<form [formGroup]="signupForm">
    <div class="container">
        <div class="form-group mb-5">
            <label for="exampleInputEmail1">Nom :</label>
            <div class="d-flex align-items-center">
                <input type="text" class="form-control" formControlName="lastname">
                <i class="fa-solid fa-lock pl-3"></i>
            </div>
        </div>
        <div class="form-group mb-5">
            <label for="exampleInputEmail1">Prenom :</label>
            <div class="d-flex align-items-center">
                <input type="text" class="form-control" formControlName="firstname">
                <i class="fa-solid fa-lock pl-3"></i>
            </div>
        </div>
        <div class="form-group mb-5">
            <label for="exampleInputEmail1">Email :</label>
            <div class="d-flex align-items-center">
                <input type="email" class="form-control" formControlName="email" id="exampleInputEmail1" aria-describedby="emailHelp">
                <i class="fa-solid fa-lock pl-3"></i>
            </div>
        </div>
        <button type="submit" class="btn btn-primary">Sauvegarder</button>
    </div>
</form>

And my form.ts

me!: Me
signupForm: FormGroup = new FormGroup({})

constructor(private meService: MeService,  private fb: FormBuilder,) {
  this.CurrentUser()
}

CurrentUser(){
  this.meService.me().subscribe(
    result => {
      this.me = result
    }
  ) 
}
get lastname(): FormControl {
  return this.signupForm.get('lastname') as FormControl;
}

get firstname(): FormControl {
  return this.signupForm.get('firstname') as FormControl;
}

get email(): FormControl {
  return this.signupForm.get('email') as FormControl;
}

ngOnInit(): void {
  this.signupForm = this.fb.group({
    lastname: [
      this.me.lastname,
      [
        Validators.required,
        Validators.maxLength(30),
        Validators.minLength(2),
        Validators.pattern("^[a-zA-Z éèàâëê'-]+$"),
      ]
    ],
    firstname: [
      this.me.firstname,
      [
        Validators.required,
        Validators.maxLength(30),
        Validators.minLength(2),
        Validators.pattern("^[a-zA-Z éèàâëê'-]+$"),
      ]
    ],
    email: [
      this.me.email,
      [
        Validators.required,
        Validators.email,
      ],
    ],
  })
}

And i'm getting those errors : ERROR Error: Cannot find control with name: 'lastname' ERROR Error: Cannot find control with name: 'firsname' ERROR Error: Cannot find control with name: 'email'

How can I handle this ? please


Solution

  • The initial errors I suspect are because you first define your FormGroup as an empty object, thus it doesn't have those values. Setting at least some sort of skeleton for it would probably fix those. getters are fired constantly, if you were to put a break point in one you would see that it keeps getting hit all the time, so odds are that at load time before the form had a chance to be hydrated yet, you are trying to get a control that doesn't exist yet.

    signupForm: FormGroup = new FormGroup({
            firstname: new FormControl(),
            lastname: new FormControl(),
            email: new FormControl()
        })
    

    Conversely, it would probably be better to just define it as signupForm: FormGroup and then check for undefined in the getter itself. Ex:

    get email(): FormControl {
      return this.signupForm?.get('email') as FormControl;
    }
    

    Another thing to keep in mind is that you are making, what I suppose, is an API request. The code doesn't really wait for it to be complete, it is not blocking, so a more appropriate thing to do would be to build your actual form after you get the results build.

    this.meService.me().subscribe(
        (result: Me) => {
          if(result) { 
             this.me = result
    
             //build your form here.
          }         
        }
      )