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
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>
<!-- 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])
});
}
}
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.
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.