Where to create the FormGroup in an Angular component?

182 views Asked by At

I have angular 15 application containing Projects and Todos. and wondering where in my project component to create the following formgroup:

public todoForm: UntypedFormGroup = this.builder.group({});

The full context is :

/**
 * Project component.
 */
@Component({
  selector: 'project',
  templateUrl: './project.component.html',
  styleUrls: ['./project.component.scss']
})
export class ProjectComponent implements OnInit, OnDestroy {
  public currentProject?: Project;
  public currentTodo?: Todo;
  // ? here
  public loading = false;   
  public currentLang: string = "";    
  private onDestroy = new ReplaySubject(1);

  constructor(
    private storage: LocalStorageService,
    private translateService: TranslateService,
    private changeDetectorRef: ChangeDetectorRef,
    private todoService: TodoService,
    private projectService: ProjectService,
    public todoForm: UntypedFormGroup,          // PROBLEM
    public settingsService: SettingsService,
    private builder: UntypedFormBuilder,
    private notyfService: NotyfService,
    private route: ActivatedRoute,
    private router: Router,
  ) {
    this.todoForm = this.builder.group({});    // PROBLEM
  }

I also read this solution.

It was initially like this (out of constructor)

export class ProjectComponent implements OnInit, OnDestroy {
  public currentProject?: Project;
  public currentTodo?: Todo;
  public todoForm: UntypedFormGroup = this.builder.group({});

however in that case it complained the builder is null...

What to do? I read also this solution, but it is not clear where should I create that element.

enter image description here

If I do initialization in constructor without "?" the compiler is happy; however it will throw error in runtime:

core.mjs:9095 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(ProjectModule)[FormGroup -> FormGroup -> FormGroup -> FormGroup]: NullInjectorError: No provider for FormGroup!

PS.

As the html of project component is like this

<div class="col" [formGroup]="todoForm">
  <kendo-tabstrip tabPosition="right" [keepTabContent]="true" #tabstrip>
  </kendo-tabstrip>
</div>

I added the following

export class ProjectComponent implements OnInit, OnDestroy {
  @ViewChild('tabstrip') public tabstrip: TabStripComponent | undefined;

I have no more the error null error, but now it throws another error

app-routing.module.ts:18 ERROR Error: Uncaught (in promise): ChunkLoadError: Loading chunk Client_app_project_project_module_ts failed. (missing: http://localhost:4200/Client_app_project_project_module_ts.js) ChunkLoadError: Loading chunk Client_app_project_project_module_ts failed. (missing: http://localhost:4200/Client_app_project_project_module_ts.js) at webpack_require.f.j (jsonp chunk loading:27:1) at ensure chunk:6:1

1

There are 1 answers

7
Garuno On

You can initialize the formGroup in the constructor but usually you initialize it in ngOnInit. The problem is, that you expect the formGroup as a parameter to your constructor, which obviously does not work. Do it like this:

/**
 * Project component.
 */
@Component({
  selector: 'project',
  templateUrl: './project.component.html',
  styleUrls: ['./project.component.scss']
})
export class ProjectComponent implements OnInit, OnDestroy {
  public currentProject?: Project;
  public currentTodo?: Todo;

  public loading = false;

  //public errors: ErrorEntry[] = [];
  public currentLang: string = "";

  private onDestroy = new ReplaySubject(1);

  //We need to declare our variable here
  public todoForm: UntypedFormGroup;

  constructor(
    private storage: LocalStorageService,
    private translateService: TranslateService,
    private changeDetectorRef: ChangeDetectorRef,
    private todoService: TodoService,
    private projectService: ProjectService,
    public settingsService: SettingsService,
    private builder: UntypedFormBuilder,
    private notyfService: NotyfService,
    private route: ActivatedRoute,
    private router: Router,
  ) {
    this.todoForm = this.builder.group({})
  }