0

I'm getting some weird behavior which I don't know how to deal with.

I have a template which is one big form, but I'll show only single input filed where the errors is showing.

    <form [formGroup]="myForm" (ngSubmit)="submitForm()" class="row g-3 needs-validation" novalidate>

                <div class="col-md-4">
                  <label for="idCourse" class="form-label">ID</label>
                  
                  <input type="text" class="form-control" [value]="course['id']"  disabled id="idCourse" >
                </div>
    </form>

Now, in .ts file I'm basically fetching DTO from a service and initializing FormControl with bunch of FormGroups. They all work correct and map on the template as expected. But once I use service from backend I'm getting an error.

 initReactiveForm() {
            
        this.myForm = this.fb.group({
         // id:[this.course['id'],   [ ]], since this input field is disabled I'm not adding it to form, but I tried adding it as well, didn't do the job
          name:[this.course['name'], [Validators.required, Validators.minLength(3),  Validator.cannotContainWhitespaceOnly]],
    
        })
    
 }

Inside ngOnInit()

ngOnInit(): void {

    this.activatedRoute.paramMap.subscribe(params => {
      var courseId = params.get('courseIdPlaceholder');

      //some custom validation and simple checks...
    
      if (courseId) {
        

        //check in service layer if Course exists for given Id; this won't work
        this.firebaseService.getCourseById(courseId).subscribe(course => {

           this.course = course ;
           this.initReactiveForm();

        });

        //this.course = Builider(Course).id("1").build(); but this works if I comment out above code which fetches Course from service
       // this.initReactiveForm();

      } else {
        alert("Not valid id!")
        this.router.navigate(["/home"]);
        return;
      }

    });
    
  }

The error I'm getting looks like this:

    core.mjs:6485 ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

      Example:

      
  <div [formGroup]="myGroup">
    <input formControlName="firstName">
  </div>

  In your class:

  this.myGroup = new FormGroup({
      firstName: new FormControl()
  });
    at missingFormException (forms.mjs:1494:12)
    at FormGroupDirective._checkFormPresent (forms.mjs:5523:19)
    at FormGroupDirective.ngOnChanges (forms.mjs:5296:14)
    at FormGroupDirective.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:1508:1)
    at callHook (core.mjs:2552:1)
    at callHooks (core.mjs:2511:1)
    at executeInitAndCheckHooks (core.mjs:2462:1)
    at selectIndexInternal (core.mjs:8405:1)
    at Module.ɵɵadvance (core.mjs:8388:1)
at CourseComponent_Template (course.component.html:9:59)

Line course.component.html:9:59 points at the beginning of [value]="course['id'] in the template.

If I don't use firebaseService and just hardcode a object, this.course = Builider(Course).id("1").build(); then, form populates and everything works and no error in console.

Here is the service:

public getAllCourses() : Observable<Course[]>{
    return this.fireDb.list<Course>('courses').valueChanges();
   
}

I'm actually fetching all the courses from Firebase and in subscribe() I take the first Course. Everything is console.log-ed and I have values I want. But somehow the template renders before I get the object.

Just to be clear, my form does in fact gets populated, but I'm getting this error which annoys me so much.

2
  • 1
    You have no formControlName on your input it seems..? Commented Mar 10, 2022 at 0:17
  • Same error occurs when I set in input formControleName="id" and uncomment 'id' in formGroupe. Commented Mar 10, 2022 at 7:59

1 Answer 1

1

Since you're initializing the myForm FromGroup synchronously within the subscribe of the paramMap and getCourseById, then the component template won't be able (while the initialization) to recognize the myForm instance which is null before initializing it in the initReactiveForm method.

I think to resolve this issue you either need to:

  • Add *ngIf="myForm", to render the form element only after initializing the myForm.
  • OR initialize the myForm directly within the ngOnInit, then you can patchValue to it once the data comes from the getCourseById.
Sign up to request clarification or add additional context in comments.

Comments

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.