简体   繁体   中英

'missingFormException ' in Angular using Reactive forms?

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM