ERROR Error: No value accessor for form control with name: - angular-reactive-forms

I have followed
the following guide
Angular-Reactive forms
I modified a bit the code to put it in a module, adding some fields to the originals model and it worked.
after upgrading to angular 8, the module is still working, but the console in Chrome for every control gives me this error:core.js:6150 ERROR Error: No value accessor for form control with name: 'title' at _throwError (forms.js:2603) at setUpControl (forms.js:2377) at FormGroupDirective.addControl (forms.js:5699) at FormControlName._setUpControl (forms.js:6274) at FormControlName.ngOnChanges (forms.js:6219) at FormControlName.rememberChangeHistoryAndInvokeOnChangesHook (core.js:1506) at callHook (core.js:2525) at callHooks (core.js:2492) at executeInitAndCheckHooks (core.js:2443) at selectIndexInternal (core.js:8389)
this is my code for question-form-component.html:
<div [formGroup]="form">
<label [attr.for]="question?.key">{{ question?.label }}</label>
<div [ngSwitch]="question?.controlType">
<input
ngDefaultControl
*ngSwitchCase="'textbox'"
[formControlName]="question?.key"
[id]="question?.key"
[type]="question?.type"
[value] = "question?.value"
/>
<div [ngSwitch]="question?.controlType">
<ion-textarea
ngDefaultControl
*ngSwitchCase="'textArea'"
[formControlName]="question?.key"
[id]="question?.key"
autoGrow="question?.autoGrow"
[value]= "question?.value"
></ion-textarea>
</div>
<div *ngSwitchCase="'barcodeScanner'">
<app-barcode-scanner
[formControlName]="question?.key"
(ngModelChange)="question?.onChange($event)"
[id]="question?.key"
[value]="question?.value"
></app-barcode-scanner>
</div>
<div *ngSwitchCase="'datebox'">
<ion-datetime [formControlName]="question?.key" [id]="question?.key">
</ion-datetime>
</div>
<div *ngSwitchCase="'switchBox'">
<p class="switchText">
{{ getValue ? question.labelTrue : question.labelFalse }}
</p>
<ion-icon
[name]="getValue ? question.iconTrue:question.iconFalse"
></ion-icon>
<ion-toggle
[formControlName]="question?.key"
[id]="question?.key"
></ion-toggle>
</div>
<div
[formControlName]="question?.key"
[id]="question?.key"
>
<div *ngSwitchCase="'itemSelector'"
[formControlName]="question?.key"
[id]="question?.key"
ngDefaultControl
>
<app-selector-items
[formControlName]="question?.key"
[id]="question?.key"
[text]="question?.text" [service]="question?.service" (selectedItem)="question.selectedItem($event)"
[sorterFunction]="question?.sorterFunction"
[filterFunction]="question?.ItemsFilterFunction"
[createPopup]= "question?.createPopup"
[item]="question?.value"
(selectedItem)="question.selectedItem($event)" >
</div>
<select
[id]="question?.key"
*ngSwitchCase="'dropdown'"
[value]="question?.value"
[formControlName]="question?.key"
>
<option *ngFor="let opt of question?.options" [value]="opt?.value">{{
opt.key
}}</option>
</select>
<div *ngSwitchCase="'geobox'">
<input-geolocation
[id]="question?.key"
[address]="question.value?.adress"
[formControlName]="question?.key"
(ngModelChange)="question?.onChange($event)"
></input-geolocation>
</div>
{{ question ? question.label : "" }} is required
this is my question-form-component.ts:
import {
Component,
Input,
OnInit,
Output,
EventEmitter,
ChangeDetectionStrategy,
ɵConsole,
OnChanges,
SimpleChanges
} from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
import { QuestionBase } from '../../models/question-base';
#Component({
selector: 'app-question',
templateUrl: './question-form-component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class QuestionFormComponent implements OnInit, OnChanges {
public value: any;
#Input() question: QuestionBase;
#Input() form: FormGroup;
ngOnInit() {
this.value = this.question ? this.question.value : undefined;
this.form = this.form
? this.form
: new FormGroup({
// I need an instance of formgroup for run the tests
name: new FormControl(this.question.key),
value: new FormControl(this.question.value)
});
}
ngOnChanges(changes: SimpleChanges) {
}
get isValid() {
return this.question ? this.form.controls[this.question.key].valid : false;
}
get getValue() {
return this.question.key ? this.form.get(this.question.key).value : '';
}
getIcon() {
return this.form.get(this.question.key).value ? String(this.question.iconTrue) : String(this.question.iconFalse)
}
}
thanks in advance

Related

binding form using formGroup in angular component

I'm facing below error while binding the form
cart.component.html
<h3>Cart</h3>
<p>
<a routerLink="/shipping">Shipping Prices</a>
</p>
<div class="cart-item" *ngFor="let item of items">
<span>{{ item.name }} </span>
<span>{{ item.price | currency }}</span>
</div>
<form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
<div>
<label for="name">
Name
</label>
<input id="name" type="text" formControlName="name">
</div>
<div>
<label for="address">
Address
</label>
<input id="address" type="text" formControlName="address">
</div>
<button class="button" type="submit">Purchase</button>
</form>
cart.component.ts
import { Component } from '#angular/core';
import { FormBuilder } from '#angular/forms';
import { CartService } from '../cart.service';
#Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css']
})
export class CartComponent {
items = this.cartService.getItems();
checkoutForm = this.formBuilder.group({
name: '',
address: ''
});
constructor(
private cartService: CartService,
private formBuilder: FormBuilder,
) {}
onSubmit(): void {
// Process checkout data here
this.items = this.cartService.clearCart();
console.warn('Your order has been submitted', this.checkoutForm.value);
this.checkoutForm.reset();
}
}
error :
Failed to compile.
src/app/cart/cart.component.html:12:7 - error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.
12 <form [formGroup]="checkoutForm" (ngSubmit)="onSubmit()">
~~~~~~~~~~~~~~~~~~~~~~~~~~
src/app/cart/cart.component.ts:8:16
8 templateUrl: './cart.component.html',
~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component CartComponent.
just add into your app.module.ts
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
and under #NgModule
#NgModule({
imports: [
FormsModule,
ReactiveFormsModule,

how to upload csv file nuxtjs to API

Nuxt.js I searched lots of tutorials for CSV uploading using laravel API but I did not get logic on how to code csv uploading things help me to solve this or give tutorial links.
Modules
import { AxiosResponse } from "axios";
import { axios } from "#/plugins/axios";
export default {
async importVsim(params: any): Promise<AxiosResponse<null>> {
return await <AxiosResponse>axios.post('v1/ucl/import',params);
}
}
Components
<template>
<div style="display:inline; text-align:left;">
<b-button icon-left="upload" #click="open">UCL CSV</b-button>
<b-modal
v-model="showModal"
trap-focus
aria-role="dialog"
aria-label="Example Modal"
:width="600"
aria-modal>
<div class="card mb-4">
<header class="card-header">
<p class="card-header-title">UCL CSV</p>
</header>
<div class="card-content">
<b-field label="mnk_*.csv">
<b-upload v-model="file1" class="file-label">
<span class="file-cta">
<b-icon class="file-icon" icon="upload"></b-icon>
<span class="file-label">Click to upload</span>
</span>
<span class="file-name" v-if="file1">
{{ file1.name }}
</span>
</b-upload>
</b-field>
<b-field label="htk_*.csv">
<b-upload v-model="file2" class="file-label">
<span class="file-cta">
<b-icon class="file-icon" icon="upload"></b-icon>
<span class="file-label">Click to upload</span>
</span>
<span class="file-name" v-if="file2">
{{ file2.name }}
</span>
</b-upload>
</b-field>
<div style="text-align:center;">
<b-button #click="close" :loading="loading">cancel</b-button>
<b-button class="is-primary" #click="upload" :loading="loading">Ok</b-button>
</div>
</div>
</div>
</b-modal>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator"
import importCsv from "#/modules/importCsv"
#Component({})
export default class extends Vue {
file1: any = null
file2: any = null
loading: boolean = false
showModal: boolean = false
errors: any = {}
async upload() {
const response = await importCsv.importVsim(this.file2)
console.log(response)
}
open() {
this.errors = {}
this.showModal = true
}
close() {
this.showModal = false
}
}
</script>

Angular6 filter

I'm trying to build a filter pipe in Angular 6, but it's not working properly.
.html
<form>
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" name="searchString" placeholder="Type to search..." [(ngModel)]="searchString">
</div>
</div>
</form>
<table class="table">
<tr *ngFor="let user of users | filter2 : searchString">
{{user.name}}
</tr>
</table>
pipe
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'filter2'
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) return [];
if (!searchText) return items;
searchText = searchText.toLowerCase();
return items.filter(it => {
return it.toLowerCase().includes(searchText);
});
}
}
I get this error when I write inside input:
ERROR TypeError: it.toLowerCase is not a function
What am I doing wrong? Thank you for your time!
users
You can try it.name.toString().toLowerCase().includes(searchText);
Component
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
users:any[];
constructor(){
this.users = [
{name:"John"},
{name:"Tom"},
{name:"Carlton"},
{name:"Judy"},
{name:"Ada"}
];
}
}
Html
<form>
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" name="searchString" placeholder="Type to search..." [(ngModel)]="searchString">
</div>
</div>
</form>
<table class="table">
<tr *ngFor="let user of users | filter2 : searchString">
{{user.name}}
</tr>
</table>
Pipe
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'filter2'
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) return [];
if (!searchText) return items;
searchText = searchText.toLowerCase();
return items.filter(it => {
return it.name.toLowerCase().includes(searchText);
});
}
}

Angular 2 - Required field validation if checkbox is selected

Hy guys I'm new to Angular2 and in JS frameworks in general. I'm flowing tutorials on official site and haven't been able to find the solution to this problem.
So I have checkbox which is optional but if the checkbox is "checked" a new input field is shown. this part is not a problem. The problem is that I'm using modal based validation and I can't figure out how to make this new input field required only if the checkbox is checked.
this is may implementation so far:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<!--{{form}}-->
<div formGroupName="test">
<div class="field">
<div class="checkbox">
<input type="checkbox" name="entryRecurring" value="" id="entryRecurring" formControlName="entryRecurring" />
<label for="entryRecurring">
<div class="checkbox_icon"></div>
Recurring Entry
</label>
</div>
</div>
<div *ngIf="form.value.test.entryRecurring">
<div class="field">
<label for="entryRecurringAmount">Repeat Amount</label>
<input type="text" name="entryRecurringAmount" value="" id="entryRecurringAmount" formControlName="entryRecurringAmount" />
</div>
</div>
</div>
<div class="field last">
<button name="submit" id="submit" class="btn btn_sushi" [disabled]="!form.valid">Submit</button>
</div>
import {Component, Input, OnInit, OnChanges} from '#angular/core';
import { Validators } from '#angular/common';
import { REACTIVE_FORM_DIRECTIVES, FormGroup, FormControl, FormBuilder } from '#angular/forms';
import { FormMessages } from './../helpers/formMessages.component';
import {EntriesService} from './entries.service';
import {ValidationService} from '../helpers/validation.service';
import {Category, CategoryByType} from '../../mock/mock-categories';
#Component({
selector: 'entryForm',
templateUrl: 'app/components/entries/entriesEdit.template.html',
directives: [REACTIVE_FORM_DIRECTIVES, FormMessages],
providers: [EntriesService, ValidationService]
})
export class EntriesEditComponent implements OnInit, OnChanges {
#Input() control: FormControl;
public form:FormGroup;
public submitted:boolean = false;
// private selectedId: number;
categories: Category[];
categoriesSortedByType: CategoryByType[];
constructor(
private _fb:FormBuilder,
private _entriesService: EntriesService
// private _router: Router
) {
this.form = this._fb.group({
test: this._fb.group({
entryRecurring: [''],
entryRecurringAmount: [''],
})
});
}
onSubmit() {
this.submitted = true;
// console.log(this.form.value);
if (this.form.dirty && this.form.valid) {
this._entriesService.saveEntry(this.form.value);
}
}
You could do that by using a custom validation service.
import {NgFormModel} from "angular2/common";
import {Component, Host} from 'angular2/core';
#Component({
selector : 'validation-message',
template : `
<span *ngIf="errorMessage !== null">{{errorMessage}}</span>
`,
inputs: ['controlName : field'],
})
export class ControlMessages {
controlName : string;
constructor(#Host() private _formDir : NgFormModel){
}
get errorMessage() : string {
let input = this._formDir.form.find(this.controlName);
let checkBx = this._formDir.form.find('checkBoxName');
if(input.value.trim() === '' && checkBx.checked) {
return 'The input field is now required'
}
return null;
}
}
Then use the new component like bellow
<div *ngIf="form.value.test.entryRecurring">
<div class="field">
<label for="entryRecurringAmount">Repeat Amount</label>
<input type="text" name="entryRecurringAmount" value="" id="entryRecurringAmount" ngControl="entryRecurringAmount" />
<validation-message field="entryRecurringAmount"></validation-message>
</div>
</div>
Hope that helped!

Angular2 How to pass a method located in other file

I am quite a noob in Angular2 and typescript.
I want to pass a method from other class in a other file.
This is the file iam talking about in specific i want to pass the method deleteCondition():
export class ConditionBuilderComponent implements OnInit {
conditions: Condition[] = [];
catalog: Condition[] = [];
constructor(private _conditionService: ConditionService) { }
getConditions() {
this._conditionService.getConditions().then(conditions => this.catalog = conditions);
}
ngOnInit() {
this.getConditions();
}
onChange(conditionsIndex, catalogIndex) {
//console.log(selectedCondition);
//console.log(conditionsIndex);
console.log(catalogIndex);
this.conditions[conditionsIndex] = this.catalog[catalogIndex];
}
newCondition() {
this.conditions.push(this.catalog[0]);
}
deleteCondition() {
this.conditions.pop();
}
}
I want to pass the deleteCondition() method to an other file because in the other file this.conditions.pop() is not recognised of course.
First it was like this: https://www.dropbox.com/s/92z2oe7f4w5x2b5/conditions.jpg?dl=0
Here it deletes the last created but i want to delete each condition separately like this:
https://www.dropbox.com/s/ptwq6sk6da4p21k/new.jpg?dl=0
This is the code from the SelectCondition:
import {Component} from 'angular2/core';
import {Condition} from './condition';
import {ConditionBuilderComponent} from "./conditionbuilder.component";
#Component({
selector: 'select-condition',
template: `
<div class="col-xs-3">
<div class="form-group">
<select class="form-control" [(ngModel)]="selectedOperator">
<option *ngFor="#operator of selectOperators">{{operator}}</option>
</select>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<div class="input-group">
<span class="btn-file">
<input type="file" (click)="selectFile()" multiple />
</span>
<input type="text" [(ngModel)]="fileValue" class="form-control" readonly>
<span class="input-group-addon">
<span class="glyphicon glyphicon-folder-open"></span>
</span>
</div>
</div>
</div>
<a class="btn btn-danger pull-right" (click)="deleteCondition()"><i class="glyphicon glyphicon-minus"></i></a>
`
})
export class SelectCondition extends Condition {
public name: string = 'select';
public fileValue: string;
public selectedOperator: string = 'in';
public selectOperators: Condition[] = [
"in"
];
selectFile() {
$(document).on('change', '.btn-file :file', function() {
var input = $(this),
numFiles = input.get(0).files ? input.get(0).files.length : 1,
label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
input.trigger('fileselect', [numFiles, label]);
});
$('.btn-file :file').on('fileselect', function(event, numFiles, label) {
var input = $(this).parents('.input-group').find(':text'),
log = numFiles > 1 ? numFiles + ' files selected' : label;
if( input.length ) {
input.val(log);
console.log(input.val());
}
});
}
deleteCondition = () => this.deleteCondition();
}
Please help me out.

Resources