angularformsform-controlangular-abstract-control

Problems with FormControl and AbstractControl in angular


I'm following a online course but I have lots of problems with that.

I depends on I put on my code I get

type 'abstractcontrol' is missing the following properties from type 'formcontrol': registerOnChange, registerOnDisable, _applyFormState

or

type Abstractcontrol is not assignable to type formcontrol

In the TS of my Component I have

import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import {  FormBuilder, FormGroup } from '@angular/forms';
import { DestinoViaje } from '../models/destino-viaje.model';

@Component({
  selector: 'app-form-destino-viaje',
  templateUrl: './form-destino-viaje.component.html',
  styleUrls: ['./form-destino-viaje.component.css']
})
export class FormDestinoViajeComponent implements OnInit {

  @Output() onItemAdded: EventEmitter<DestinoViaje>;
  fg: FormGroup;

  constructor(fb: FormBuilder) {
    this.onItemAdded = new EventEmitter();
    this.fg = fb.group({
      nombre: [''],
      url: ['']
    });
    console.log(this.fg);

  }

  ngOnInit(): void {


  }

  guardar(nombre: string, url: string): boolean {
    let d = new DestinoViaje(nombre, url);
    this.onItemAdded.emit(d);
    return false;

  }

}

and in the HTML of my Component I Have

<form
        [formGroup]="fg"
        (ngSubmit)="guardar(
                                fg.controls['nombre'].value,
                                fg.controls['url'].value
                    )">
  <div class="form-group">
    <label for="nombre">Nombre</label>
    <input type="text" class="form-control"
            id="nombre" placeholder="Ingresar nombre..."
            [formControl]="fg.controls['nombre']">
  </div>
  <div class="form-group">
    <label for="Imagen Url">Imagen Url</label>
    <input type="text" class="form-control"
            id="imagenUrl" placeholder="Ingresar url..."
            [formControl]="fg.controls['url']">
  </div>
  <button type="submit" class="btn btn-primary">Guardar!</button>
</form>

I'm not sure in which version the example is, but I'm using Angular 11.05

Thanks in advance.

Regards

Nicolas


Solution

  • This is because your nombre and url are not control fields, you are making them an array of an empty string. you should create them like

    this.fg = fb.group({
          nombre: this.fb.control(/*initial value*/'', /*validators that they should pass*/[]')',
          url:this.fb.control(/*initial value*/'', /*validators that they should pass*/[]')'
    });
    

    So you create a FormControl instead of Array<string>

    Here's a template sample using reactive forms:

    <!-- component.template.html -->
    
    <form [formGroup]="group">
        <input type="email" formControlName="email">
        <input type="password" formControlName="passw">
        <!-- more inputs maybe -->
    </form>
    
    @Component({...})
    export class YourComponent implements OnInit {
    
        // This is our reactive form that we want to use
        group: FormGroup;
    
        constructor(private fb: FormBuilder) {}
    
        ngOnInit() {
            const fb = this.fb; // So we write less code
            this.group = fb.group({
                // On the left side we use the formControlName that we are going to use in the html
                // then, on the control we pass the default value of the input and an array of validators. 
                // Validators are just functions that may return errors given a certain control input.
                email: fb.control('', [Validators.required]),
                // Remember that passw is what we used on the formControlName of the template
                passw: fb.control('', [Validators.required])
            });
        }
    
    }
    

    Some notes:

    Given your confusion, if you check here you will see that there's an example doing what you did:

    Just using a FormControl in case you have a single input that doesn't belong to any <form> or FormGroup. When you have a full form, if you scroll down, you'll see an example that looks more what I gave you in my last edit of my answer.

    Final answer

    No it's not because different versions of Angular but different use-cases of the ReactiveForms of Angular. One uses a form and the other does not.