Error + JSON + <select> + <option> - json

I'm getting a very strange error after I upgraded to Angular 6.0.9. My template has a select, where there is an opnion with a value of "" and an "Select an Option" label, and the other options are generated by a list that comes from the bank.
So when I need to clear the form I call the formBuilder again. However, when I clean the form, a request occurs to api and consequently a json error, warning that it can not serialize a null value.
During the reset of the form I do not call any method that triggers the API, so I'm not sure what to do.
It is worth mentioning that the application still works, but it presents the user with an error message, since I have an interceptor that receives all errors and prints in a snack bar...
Template:
<select class="form-control" id="selectTipoDocumento" formControlName="tipoDocumento" [compareWith]="equals"
[class.is-valid]="this.docForm.controls['tipoDocumento'].valid &&
(this.docForm.controls['tipoDocumento'].touched || this.docForm.controls['tipoDocumento'].dirty)"
[class.is-invalid]="!this.docForm.controls['tipoDocumento'].valid &&
(this.docForm.controls['tipoDocumento'].touched || this.docForm.controls['tipoDocumento'].dirty)">
<option value="">Selecione um tipo</option>
<option *ngFor="let tipo of tiposDocumento" [ngValue]="tipo">{{tipo?.nome}}</option>
</select>
Component:
export class DocumentoDetalheComponent implements OnInit {
docForm: FormGroup;
tiposDocumento: TipoDocumento[];
documento: Documento = new Documento();
constructor(
private fb: FormBuilder,
private tipoDocumentoService: TipoDocumentoService,
private documentoService: DocumentoService,
private route: ActivatedRoute
) {}
ngOnInit() {
const idRota: string = this.route.snapshot.params["id"];
this.createFormGroup();
this.tipoDocumentoService.findAll().subscribe(
obj => {
this.tiposDocumento = obj;
},
error => { }
).unsubscribe;
if (idRota != null){
this.documentoService.findById(idRota).subscribe(
obj => {
this.documento = obj;
this.docForm.setValue({
tipoDocumento: this.documento.tipoDocumento,
resumo: this.documento.resumo,
observacao: this.documento.observacao
});
},
error => { }
);}
}
onSubmit() {
let docTemp: Documento = this.docForm.value;
this.documento.tipoDocumento = docTemp.tipoDocumento;
this.documento.resumo = docTemp.resumo;
this.documento.observacao = docTemp.observacao;
if (this.documento.id == null) {
this.save(this.documento);
} else {
this.update(this.documento);
}
}
save(documento: Documento) {
this.documentoService
.insert(documento)
.subscribe(response => console.log(response));
}
update(documento: Documento) {
this.documentoService.update(documento).subscribe(response => console.log(response));
}
createFormGroup() {
this.docForm = this.fb.group({
tipoDocumento: ["", [Validators.required]],
resumo: ["",[Validators.required, Validators.minLength(5), Validators.maxLength(60)]],
observacao: ["", [Validators.maxLength(500)]]
});
}
limparForm() {
this.createFormGroup();
}
equals(tp1: TipoDocumento, tp2: TipoDocumento) {
return tp1.id === tp2.id
}
voltar() {}
}
API error:
2018-07-16 10:05:43.186 WARN 4996 --- [ tomcat-http--5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `br.mp.mpce.sge.domain.TipoDocumento` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value (''); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `br.mp.mpce.sge.domain.TipoDocumento` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('')
at [Source: (PushbackInputStream); line: 1, column: 579] (through reference chain: br.mp.mpce.sge.domain.Documento["tipoDocumento"])

I found the solution. The problem was in my formGroup, where I was using ngSubmit, so all buttons in my form were submitting API requests. So, the solution was to remove ngSubmir from the form, as well as manually set, in the event (click), the necessary methods.
<form [formGroup]="docForm" novalidate>
<div class="card">
<div class="card-body">
<div class="form-group row" *ngIf="documento?.id != null">
<div class="form-group col-md-3">
<label for="setor">Nº Protocolo: </label>
</div>
<div class="form-group col-md-6">
{{documento?.codigo}}/{{documento?.ano}}
</div>
</div>
<div class="form-group row" *ngIf="documento?.id != null">
<div class="form-group col-md-3">
<label for="setor">Setor cadastro: </label>
</div>
<div class="form-group col-md-6">
{{documento?.setorCadastro?.nome}}
</div>
</div>
<div class="form-group row">
<div class="form-group col-md-3">
<label for="selectTipoDocumento">Tipo de Documento: </label>
</div>
<div class="form-group col-md-6">
<select class="form-control" id="selectTipoDocumento" formControlName="tipoDocumento" [compareWith]="equals"
[class.is-valid]="this.docForm.controls['tipoDocumento'].valid &&
(this.docForm.controls['tipoDocumento'].touched || this.docForm.controls['tipoDocumento'].dirty)"
[class.is-invalid]="!this.docForm.controls['tipoDocumento'].valid &&
(this.docForm.controls['tipoDocumento'].touched || this.docForm.controls['tipoDocumento'].dirty)">
<option value="">Selecione um tipo</option>
<option *ngFor="let tipo of tiposDocumento" [ngValue]="tipo">{{tipo?.nome}}</option>
</select>
</div>
<div class="form-group col-md-3 invalid-feedback d-block"
*ngIf="!this.docForm.controls['tipoDocumento'].valid && (this.docForm.controls['tipoDocumento'].touched || this.docForm.controls['tipoDocumento'].dirty)">
Tipo dodocumento é obrigatório
</div>
</div>
<div class="form-group row">
<div class="form-group col-md-3">
<label for="inputResumo">Resumo: </label>
</div>
<div class="form-group col-md-6">
<input type="text" class="form-control" id="inputResumo" formControlName="resumo" placeholder="Resumo do documento" maxlength="60"
autocomplete="off"
[class.is-valid]="this.docForm.controls['resumo'].valid && (this.docForm.controls['resumo'].touched || this.docForm.controls['resumo'].dirty)"
[class.is-invalid]="!this.docForm.controls['resumo'].valid && (this.docForm.controls['resumo'].touched || this.docForm.controls['resumo'].dirty)">
</div>
<div class="form-group col-md-3 invalid-feedback d-block"
*ngIf="!this.docForm.controls['resumo'].valid && (this.docForm.controls['resumo'].touched || this.docForm.controls['resumo'].dirty)">
Resumo é obrigatório (5 a 60 caracteres)
</div>
</div>
<div class="form-group row">
<div class="form-group col-md-3">
<label for="inputObservacao">Observação: </label>
</div>
<div class="form-group col-md-6">
<textarea type="text" class="form-control" id="inputObservacao" formControlName="observacao" rows="5">
</textarea>
</div>
</div>
<div class="form-group row">
<div class="form-group col-md-3">
</div>
<div class="form-group col-md-2">
<button class="btn btn-primary btn-block" (click)="limparForm()">Limpar</button>
</div>
<div class="form-group col-md-2">
<button class="btn btn-success btn-block"[disabled]="!docForm.valid" (click)="onSubmit()">Salvar</button>
</div>
<div class="form-group col-md-2">
<a class="btn btn-primary btn-block" [routerLink]="['/']">Voltar</a>
</div>
</div>
</div>
</div>
</form>

Related

how can i edit a form array

I have an application where I want to edit the information of a FormArray, but I input!
I can create data, but I cannot edit it.
I've already tried to create another matrix form, but it still doesn't have any connection form when trying to edit data that already exists within this one.
my typescript code:
ngOnInit(): void {
this.projectInfoService.retrieveById(+this.activatedRoute.snapshot.paramMap.get('id')!).subscribe({
next: project => {
console.log(project)
this.project = project
this.rgForm = this.fb.group({
id: [this.project.id],
name: [this.project.name, Validators.required],
team: [this.project.team,],
description: [this.project.description, Validators.required],
tasks: this.fb.array([])
})
},
error: err => console.log('Error:', err)
});
}
get name() {
return this.rgForm.get('name')
}
get description() {
return this.rgForm.get('description')
}
get team() {
return this.rgForm.get('team')
}
get tasks(): FormArray {
return <FormArray>this.rgForm.get('tasks');
}
my html code:
<ng-container formArrayName="tasks" *ngFor="let task of tasks.controls; let i=index">
<div [formGroupName]="i" class="d-flex justify-content-center aling-items-center my-2">
<div class="col-md-5">
<div class="form-floating">
<input type="text" formControlName="nameTask" [attr.id]="'task' + i" id="floatingInputGridT"
class="form-control" placeholder="Nome da tarefa" required>
<label [attr.for]="'task' + i" for="floatingInputGridT">Tarefa</label>
</div>
</div>
<div class="col-md-5">
<div class="form-floating">
<select class="form-select" formControlName="member" [attr.id]="'taskMember' + i">
<option *ngFor="let member of _members" [value]="member.nameMember">{{ member.nameMember }}</option>
</select>
<label [attr.for]="'taskMember' + i">Membro da task</label>
</div>
</div>
<div class="d-flex justify-content-center aling-items-center flex-column">
<div class="col-md-1">
<button type="button" class="btn btn-danger" (click)="deleteTask(i)"><i
class="fa-solid fa-trash-can"></i></button>
</div>
</div>
</div>
</ng-container>
How can I edit the values ​​contained in this FomrArray?

Dropdown validation for default value

I need help on how to validate the default value on a select dropdown list. What I have now doesn't show the validation on the view because I have '--Select--' as the first value. What can I do to get the validation to work. It works for Order, Title, URL but not for the select dropdown. I added a value = "0" and added Range attribute in view model.
Edit: I have to change this so it uses validation summary instead of using the tags for each field but I still can't get the validation messages to show.
<form id="form-create-link" method="post" asp-controller="Link"
asp-action="CreateLink">
<div class="form-group col-md-8">
**<div asp-validation-summary="ModelOnly" id="validation-error" hidden
class="text-danger custom-validation-summary"></div>
</div>**
<input id="link-id" asp-for="#Model.LinkId" type="hidden" />
<input name="FetchCategories" type="hidden"/>
<div class="form-group col-md-8 col-lg-4">
<div class="form-group">
#{
var authorizedCommitteeTypes = await Model.CommitteeType
.ToSelectListAsync(AuthorizationService, User,
AuthRequirements.AdminCommitteeType);
if (authorizedCommitteeTypes.Count == 1)
{
<input id="committeeType" name="committeeType" type="hidden"
value="#authorizedCommitteeTypes.FirstOrDefault()?.Value" />
}
else
{
<label class="control-label">Committee Type</label>
<select id="add-edit-committee-type"
name="committeeType"
asp-for="#Model.CommitteeType"
asp-items="#authorizedCommitteeTypes"
class="form-control">
</select>
}
}
</div>
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Category</label>
#{
if (Model != null && Model.AvailableCategories != null)
{
var availableCategories =
new SelectList(
Model.AvailableCategories.OrderBy(c => c.Order),
dataValueField: "CategoryId",
dataTextField: "Title",
selectedValue: Model.CategoryId);
<select id="dropdown-linkCategories" required
asp-for="#Model.CategoryId"
asp-items="#availableCategories"
class="form-control">
<option>-- Select --</option>
</select>
}
else
{
<select id="dropdown-linkCategories"
class="form-control">
<option>-- Select --</option>
</select>
}
}
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Title</label>
<input id="title" asp-for="Title" name="Title" class="form-control" />
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">Display Order</label>
<div>
<input id="order" asp-for="Order" name="Order" class="form-control" />
</div>
</div>
<div class="form-group col-md-8 col-lg-4">
<label class="control-label">URL</label>
<input id="url" asp-for="URL" name="URL" class="form-control" />
</div>
<div class="form-group col-md-8 col-lg-12">
<label class="control-label">Description</label>
<textarea class="rtextDescription" name="Description" id="Description"
row="1" cols="60"
data-val-maxlength-max="200" asp-for="Description"
data-val-maxlength="Max length for Description is 200"></textarea>
</div>
<div class="form-group col-md-8 col-lg-12">
<label class="check " >
Add Another
<input type="checkbox" name="AddAnother">
<span class="checkmark"></span>
</label>
</div>
#{
if (Model.LinkId == 0)
{
<div class="form-group col-md-12">
<input type="submit" id="link-submit"
class="btn btn-forum col-sm-12 col-md-4 col-lg-4"
value="Add & Return to Links" />
<a asp-area="Admin"
asp-controller="Link"
asp-action="Index"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2">Back to
Links</a>
</div>
}
else
{
<div class="form-group col-md-8 col-lg-12">
<input type="submit" value="Save" id="edit-submit"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2" />
<a asp-area="Admin"
asp-controller="Link"
asp-action="Index"
class="btn btn-forum col-sm-12 col-md-2 col-lg-2">Back to
Links</a>
</div>
}
}
</form>
According to your code, it seems that the View Model contains the selected properties (such as: CommitteeType, CategoryId), after selecting item from the DropDownlist, we could get the selected value from these properties. So, to validate the DropDownList, we could add the validate attribute to these selected properties.
You could refer the following sample, it will create a custom validation attribute to check whether the selected value is valid or not:
Models:
public class Categories
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}
public class Order
{
[Required]
public int OrderId { get; set; }
[Required]
public string Title { get; set; }
[CheckSelctedValue(ErrorMessage ="Please select a valid category")]
public string CategoryId { get; set; } //DropDownList selected value
public List<Categories> AvailableCategories { get; set; } //DropDownList select items.
}
Here, create a custom validation attribute to check whether the selected value is valid or not.
public class CheckSelctedValue : ValidationAttribute
{
public override bool IsValid(object value)
{
int number;
//get the selected value and according to the condition to check whether the value is valid or not.
//try to convert the selected value to int.
bool success = int.TryParse(value.ToString(), out number);
//if the number is 0, it means user select the first item.
if (success && number !=0)
{
return true;
}
else
{
return false;
}
}
}
Controller:
public IActionResult CreateOrder()
{
Order o = new Order();
o.OrderId = 1001;
o.Title = "AA";
o.AvailableCategories = new List<Categories>()
{
new Categories(){ CategoryID=101, CategoryName="Meat"},
new Categories(){ CategoryID=102, CategoryName="Fruit"},
new Categories(){ CategoryID=102, CategoryName="Vegetables"}
};
o.CategoryId = "101";
return View(o);
}
[HttpPost]
public IActionResult CreateOrder(Order order)
{
//used to set the select items for the dropdownlist.
order.AvailableCategories = new List<Categories>()
{
new Categories(){ CategoryID=101, CategoryName="Meat"},
new Categories(){ CategoryID=102, CategoryName="Fruit"},
new Categories(){ CategoryID=102, CategoryName="Vegetables"}
};
if (ModelState.IsValid)
{
}
return View(order);
}
Code in the View Page (add value="0" to the dropdownlist first option):
#model netcore5.Models.Order
<div class="row">
<div class="col-md-4">
<form asp-action="CreateOrder">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="OrderId" class="control-label"></label>
<input asp-for="OrderId" class="form-control" />
<span asp-validation-for="OrderId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CategoryId" class="control-label"></label>
<select id="dropdown-linkCategories" required
asp-for="CategoryId"
asp-items="#(new SelectList(Model.AvailableCategories, "CategoryID","CategoryName", Model.CategoryId))"
class="form-control">
<option value="0">-- Select --</option>
</select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
The output as below:
Edit
I updated my code. I have to use the validation summary that is at the
top of the form but I can't get the validation messages to show.
<div asp-validation-summary="ModelOnly" id="validation-error" hidden class="text-danger custom-validation-summary"></div>
The issue is related to the above code.
First, if we want to show the validation message summary, we should set the asp-validation-summary attribute to All, instead of ModelOnly. More detail information, see The Validation Summary Tag Helper.
Second, since you are using hidden attribute, it will hide the validation message, so, try to remove the hidden attribute.
After updated, the code should be as below:
<div asp-validation-summary="All" id="validation-error"
class="text-danger custom-validation-summary"></div>

Angular 4 - Populate form with JSON data is not working

I have to edit data from a client. I have a form, in which I click on a button and redirects to a Form, in I want it to display the data of that client that I've just clicked.
Thing is, the form builder does not work when I try to associate each key to its value.
However, if I write down the name myself, like, hardcoded, the form builder works like a charm!.
edit-component.ts
import { FuncionForm } from './../../interfaces/funcion_form';
import { FuncionService } from './../../services/funcion.service';
import { Combobox } from './../../interfaces/combobox';
import { ComboboxService } from './../../services/combobox.service';
import { Formulario } from './../../interfaces/formulario';
import { HttpClient } from '#angular/common/http';
import { SharedService } from './../../services/shared-service.service';
import { Component, OnInit } from '#angular/core';
import { Funcion } from '../../interfaces/funcion';
import {
FormGroup,
Validators,
FormBuilder,
FormControl,
FormsModule,
ReactiveFormsModule
} from '#angular/forms';
#Component({
selector: 'app-editar-funcion',
templateUrl: './editar-funcion.component.html',
styleUrls: ['./editar-funcion.component.css']
})
export class EditarFuncionComponent implements OnInit {
funcionCD: number;
dadosFormulario : FuncionForm;
funcionFormGroup: FormGroup;
comboboxProfisArray : Combobox;
comboboxAgrupProfArray : Combobox;
comboboxAgrupCategArray : Combobox;
comboboxNacionArray : Combobox;
myForm : FormGroup;
constructor(private sharedService : SharedService,
private funcionService : FuncionService,
private funcionFormBuilder: FormBuilder,
private comboboxService: ComboboxService)
{}
ngOnInit() {
this.sharedService.currentClientCD.subscribe(message => this.funcionCD = message); // Service to get the client ID
this.funcionService.GetDadosCliente(this.funcionCD).subscribe(
(res:FuncionForm) => {
this.dadosFormulario = res; // Interface to define a client
// This works!
this.myForm = new FormGroup({
nome : new FormControl("A name"),
dt_nasc : new FormControl("1998-02-25"),
sexo : new FormControl("0"),
cd_nacion : new FormControl("PT"),
cd_agrup_prof : new FormControl("M"),
cd_profis : new FormControl("M"),
cd_categ : new FormControl("M"),
loc_trab : new FormControl("A company")
// This works!
/* This doesn't!
this.myForm = new FormGroup({
nome : new FormControl(this.dadosFormulario[0].nome),
dt_nasc : new FormControl(this.dadosFormulario[0].dt_nasc),
sexo : new FormControl(this.dadosFormulario[0].sexo),
cd_nacion : new FormControl(this.dadosFormulario[0].cd_nacion),
cd_agrup_prof : new FormControl(this.dadosFormulario[0].cd_agrup_prof),
cd_profis : new FormControl(this.dadosFormulario[0].cd_profis),
cd_categ : new FormControl(this.dadosFormulario[0].cd_categ),
loc_trab : new FormControl(this.dadosFormulario[0].loc_trab)
*/
})
}
edit-component.html
<div class="container">
<h1>Editar dados do funcionário</h1>
<hr>
<div class="card">
<div class="container">
<div class="row">
<div class="col-md-3" id="col-img">
<img src="/img/1">
</div>
<div class="col-md-9" id="col-dados">
<form class="form-horizontal" role="form" [formGroup]="myForm">
<!--
<div class="form-group row">
<label class="col-md-12 col-form-label">Local de trabalho</label>
<div class="col-md-12">
<input formControlName="loc_trab" type="text" class="form-control">
</div>
</div>
-->
<div class="form-group row">
<label class="col-md-12 col-form-label">Nome</label>
<div class="col-md-12">
<input formControlName="nome" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Data de nascimento</label>
<div class="col-md-12">
<input formControlName="dt_nasc" type="date" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Género</label>
<div class="col-md-12">
<select formControlName="sexo" type="text" class="form-control">
<option value="0">Masculino</option>
<option value="1">Feminino</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Nacionalidade</label>
<div class="col-md-12">
<select formControlName="cd_nacion" type="text" class="form-control">
<option *ngFor="let row of comboboxNacionArray" value="{{ row.cd }}">{{ row.nome }}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Agrupamento Profissional</label>
<div class="col-md-12">
<select formControlName="cd_agrup_prof" type="text" class="form-control">
<option *ngFor="let row of comboboxAgrupProfArray" value="{{ row.cd }}">{{ row.nome }}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Profissão</label>
<div class="col-md-12">
<select formControlName="cd_profis" type="text" class="form-control">
<option *ngFor="let row of comboboxProfisArray" value="{{ row.cd }}">{{ row.nome }}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Categoria Profissional</label>
<div class="col-md-12">
<select formControlName="cd_categ" type="text" class="form-control">
<option *ngFor="let row of comboboxAgrupCategArray" value="{{ row.cd }}">{{ row.nome }}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-md-12 col-form-label">Local de trabalho</label>
<div class="col-md-12">
<input formControlName="loc_trab" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<div class="col-md-12" style="padding-top: 15px;">
<button style="border-radius: 50px; float:right;" type="submit" class="btn btn-primary">Submeter</button>
</div>
</div>
</form>
</div>
</div>
</div>
Some screnshots
Working
Not working
I've searched everywhere and couldn't find a solution.
All help is apreciated!
PS: the JSON data comes like this. Thats why the "0" in this.dadosFormulario[0]
[
{
"nome": "MY NAME",
"dt_nasc": "1978-05-26T00:00:00",
"sexo": "0",
"cd_nacion": "2",
"cd_agrup_prof": null,
"cd_profis": "1",
"cd_categ": "TS",
"loc_trab": ""
}
]
To pre-populate data there are two methods of FormGroup instance. setValue() & patchValue(). After you receive the response from the server just set/patch the values using one of these methods setValue() and patchValue() both sets the value in form control of FormGroup. setValue() sets the value for each and every form control of FormGroup. you cannot omit any form control in setValue() but if you want to assign only few form controls of FormGroup then you can use patchValue().
Modified Code
ngOnInit() {
this.initializeForm();
this.sharedService.currentClientCD.subscribe(message => this.funcionCD = message); // Service to get the client ID
this.funcionService.GetDadosCliente(this.funcionCD).subscribe(
(res:FuncionForm) => {
this.dadosFormulario = res; // Interface to define a client
this.myForm.setValue(
{
nome : this.dadosFormulario[0].nome,
dt_nasc : this.dadosFormulario[0].dt_nasc,
sexo : this.dadosFormulario[0].sexo,
cd_nacion : this.dadosFormulario[0].cd_nacion,
cd_agrup_prof : this.dadosFormulario[0].cd_agrup_prof,
cd_profis : this.dadosFormulario[0].cd_profis,
cd_categ : this.dadosFormulario[0].cd_categ,
loc_trab : this.dadosFormulario[0].loc_trab
})
});
initializeForm()
{
this.myForm = new FormGroup({
nome : new FormControl(),
dt_nasc : new FormControl(),
sexo : new FormControl(),
cd_nacion : new FormControl(),
cd_agrup_prof : new FormControl(),
cd_profis : new FormControl(),
cd_categ : new FormControl(),
loc_trab : new FormControl()
}
Your this.dadosFormulario will be null on onNgOnit(), that's why you are not seeing any value in the form..
You need to use patchValue to update form once you get data from your funcionService

Angular 4 Reset Button Throws Error

I have the following form in my HTML element:
<form class="row" name="powerPlantSearchForm" (ngSubmit)="f.valid && searchPowerPlants()" #f="ngForm" novalidate>
<div class="form-group col-xs-3" >
<label for="powerPlantName">PowerPlant Name</label>
<input type="text" class="form-control-small" [ngClass]="{ 'has-error': f.submitted && !powerPlantName.valid }" name="powerPlantName" [(ngModel)]="model.powerPlantName" #powerPlantName="ngModel" />
</div>
<div class="form-group col-xs-3" >
<label for="powerPlantType">PowerPlant Type</label>
<select class="hideLabel form-control" [(ngModel)]="model.powerPlantType" name="powerPlantType" (change)="selectName();">
<option selected="" value="">--Select Type--</option>
<option [ngValue]="powerPlantType" *ngFor="let powerPlantType of powerPlantTypes">
{{ powerPlantType }}
</option>
</select>
</div>
<div class="form-group col-xs-3" [ngClass]="{ 'has-error': f.submitted && !organizationName.valid }">
<label for="organizationName">Organization Name</label>
<input type="text" class="form-control-small" name="powerPlantOrganization" [(ngModel)]="model.powerPlantOrg" #organizationName="ngModel" />
</div>
<div class="form-group col-xs-3" [ngClass]="{ 'has-error': f.submitted && !powerPlantStatus.valid }">
<label for="powerPlantStatus">PowerPlant Active Status</label>
<input type="text" class="form-control-small" name="powerPlantStatus" [(ngModel)]="model.isOnlyActivePowerPlants" #powerPlantStatus="ngModel" />
</div>
<div class="form-group col-md-3 col-xs-4">
<button [disabled]="loading" class="btn btn-primary">Search For PowerPant's...</button>
<img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
</div>
<div class="form-group col-md-3 col-xs-3">
<button class="btn btn-primary" (click)="reset(f)">Reset Search Criteria</button>
</div>
</form>
It renders fine, but when I tried to click the reset button, I get the following error:
ERROR TypeError: _co.reset is not a function
at Object.eval [as handleEvent] (HomeComponent.html:35)
at handleEvent (core.es5.js:12004)
at callWithDebugContext (core.es5.js:13465)
at Object.debugHandleEvent [as handleEvent] (core.es5.js:13053)
at dispatchEvent (core.es5.js:8602)
at core.es5.js:9213
at HTMLButtonElement.<anonymous> (platform-browser.es5.js:2651)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
Here is my component class:
export class HomeComponent implements OnInit {
// Represents the PowerPlantTypes
powerPlantTypes = ['RampUpType', 'OnOffType'];
// Represents the search form
model: any = {};
// currentUser: User;
// represents the list of PowerPlant data
powerPlants: PowerPlant[];
users: User[] = [];
constructor(private userService: UserService, private powerPlantService: PowerPlantService) {
// this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
}
ngOnInit() {
this.allPowerPlants();
}
selectName() {
alert(this.model.powerPlantType);
}
searchPowerPlants(): void {
const powerPlantSearchParams = new PowerPlantSearchParams(
this.model.powerPlantType,
this.model.powerPlantOrganization,
this.model.powerPlantName,
this.model.page,
this.model.powerPlantStatus);
this.powerPlantService.searchPowerPlants(powerPlantSearchParams).subscribe(result => {
this.powerPlants = <PowerPlant[]> result;
});
}
allPowerPlants(onlyActive: boolean = false, page: number = 1): void {
this.powerPlantService.allPowerPlants(onlyActive, page).subscribe(result => {
this.powerPlants = <PowerPlant[]> result;
});
}
}
What is this error conveying?
According to the Angular docs it seems you should call f.reset() not reset(f)
Check your component class if the function named reset actually exists.
use following code with Reset Search Criteria button
(click)='form.reset()'
no parameter is required
(click)="reset(form)" // wrong

Refresing the page on (submit) process Angular2 & Firebase

I´m trying to apply Firebase to the Admin HTML template that I found yesterday.
In the register page when I click on Sign in it reload the page instead of do the Firebase createUserWithEmailAndPass process.
This is my HTML code:
<form [formGroup]="form" (submit)="registrar(form.value)" class="form-horizontal">
<div class="form-group row" [ngClass]="{'has-error': (!name.valid && name.touched), 'has-success': (name.valid && name.touched)}">
<label for="inputName3" class="col-sm-2 control-label">Nombre</label>
<div class="col-sm-10">
<input [formControl]="name" type="text" class="form-control" id="inputName3" placeholder="Nombre completo">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!email.valid && email.touched), 'has-success': (email.valid && email.touched)}">
<label for="inputEmail3" class="col-sm-2 control-label">NIF</label>
<div class="col-sm-10">
<input [formControl]="email" type="text" class="form-control" id="inputEmail3" placeholder="NIF/DNI">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!password.valid && password.touched), 'has-success': (password.valid && password.touched)}">
<label for="inputPassword3" class="col-sm-2 control-label">Contraseña</label>
<div class="col-sm-10">
<input [formControl]="password" type="password" class="form-control" id="inputPassword3" placeholder="Introduce una contraseña">
</div>
</div>
<div class="form-group row" [ngClass]="{'has-error': (!repeatPassword.valid && repeatPassword.touched), 'has-success': (repeatPassword.valid && repeatPassword.touched)}">
<label for="inputPassword4" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input [formControl]="repeatPassword" type="password" class="form-control" id="inputPassword4" placeholder="Repite la contraseña">
<span *ngIf="!passwords.valid && (password.touched || repeatPassword.touched)" class="help-block sub-little-text">Las contraseñas no coinciden.</span>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-2 col-sm-10">
<button [disabled]="!form.valid" type="submit" class="btn btn-default btn-auth">Confirmar registro</button>
</div>
</div>
</form>
And this my functions:
nuevoUsuario(email, password) {
console.log(email);
return this.af.auth.createUser({
email: email,
password: password
});
}
public registrar(datos: Object): void {
this.submitted = true;
if (this.form.valid) {
// your code goes here
const formarCorreo = this.email.value +' #maimona.com';
console.log(formarCorreo);
this.afService.nuevoUsuario(formarCorreo.toLowerCase,
this.password).then((user) => {
this.afService.saveUserInfoFromForm(formarCorreo.toLowerCase,
this.name, this.email).then(() => {
// this.router.navigate(['login']);
})
.catch((error) => {
this.error = error;
console.log(error);
});
})
.catch((error) => {
this.error = error;
console.log(error);
});
}
}
I don´t know why when I press "Confirmar registro" it reload the page instead of do the function. Well it enter the function until
console.log(formarCorreo);
You can change the type of the button to button from submit and add the function to the buttons click
<button [disabled]="!form.valid" class="btn btn-default btn-auth"
type="button" <-- type
(click)="registrar(form.value)" <--click
>Confirmar registro</button>
type="submit will make elements to reload the form
By default, html <form> elements navigate to their target attribute.
To override this (since this is what you'll want most of the time in a single-page app), angular provides the (ngSubmit) convenience event (which uses event.preventDefault(), which would solve your case anyway, but is cleanear)
<button type="submit"> is doing HTTP request to the server. It's the same like <input type="submit">.
You can change it to ordinary <button> or prevent the submitting a form using events.