When trying to use the Angular 2 rc 3 @angular/forms module, Ionic's form elements always throw an error when adding the formControlName directive to them. For example: <ion-input type="text" formControlName="formControl1" ></ion-input>
Putting it to normal HTML input markup works OK, for example: <input type="text" formControlName="fullName" />
Ionic form elements; ion-input, ion-textarea, ion-select etc should all work with the new @angular/forms module.
Steps to reproduce:
import {disableDeprecatedForms, provideForms} from '@angular/forms';ionicBootstrap(MyApp, [ disableDeprecatedForms(), provideForms() ]);Thats the best I can do for reproducing because I can't find any Plunker examples set up with the required modules and Ionic beta 10.
Other information: (e.g. stacktraces, related issues, suggestions how to fix, stackoverflow links, forum links, etc)
The error written to the console log is:
EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in build/pages/issue-form/issue-form.html:61:39
ORIGINAL EXCEPTION: No value accessor for 'control1'
ORIGINAL STACKTRACE:
Error: No value accessor for 'control1'
at new BaseException (http://localhost:8100/build/js/app.bundle.js:2435:23)
at _throwError (http://localhost:8100/build/js/app.bundle.js:37484:11)
at Object.setUpControl (http://localhost:8100/build/js/app.bundle.js:37459:9)
at FormGroupDirective.addControl (http://localhost:8100/build/js/app.bundle.js:37027:18)
at FormControlName.ngOnChanges (http://localhost:8100/build/js/app.bundle.js:36902:32)
at DebugAppView._View_IssueFormPage0.detectChangesInternal (IssueFormPage.template.js:509:56)
at DebugAppView.AppView.detectChanges (http://localhost:8100/build/js/app.bundle.js:30588:14)
at DebugAppView.detectChanges (http://localhost:8100/build/js/app.bundle.js:30693:44)
at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:8100/build/js/app.bundle.js:30614:19)
at DebugAppView.AppView.detectChangesInternal (http://localhost:8100/build/js/app.bundle.js:30599:14)
A related post on the Ionic forum
Run ionic info from terminal/cmd prompt: (paste output below)
Cordova CLI: 5.4.0
Gulp version: CLI version 3.8.11
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.10
Ionic CLI Version: 2.0.0-beta.25
Ionic App Lib Version: 2.0.0-beta.15
OS: Windows 8.1
Node Version: v4.4.2
Hello, thanks for opening an issue with us! We are currently aware of this issue and will be working on it. There were some pretty big breaking changes in the recent refactor of the Angular 2 forms module.
Note to self and the team: this issue may be related: https://github.com/driftyco/ionic/issues/6580
This may be related to(not 100% on that): https://github.com/driftyco/ionic/issues/7010
I don't know if there is an elegant way to support both deprecated and new forms, but I suspect this issue results from importing NG_VALUE_ACCESSOR from "@angular/common" instead of from "@angular/forms".
@rapropos yeah, there are a good list of things that the Angular team changed in forms, but we're going through and updating everything so it works with the new forms (: Thanks for using Ionic!
BTW - will Ionic be supporting Angular built in validators like required, minlength, maxlength, pattern?
This is fixed for me (with ion-checkbox) as of this commit.
Yup, this should be closed with this commit: https://github.com/driftyco/ionic/commit/4d56219a4c33ca32587b83d90b014ae2e374959c
@adamdbradley this fixed input elements, but I am getting the following build error (from master):
src/components/menu/menu.ts(617,26): error TS2339: Property 'elementRef' does not exist on type 'Backdrop'.
@vidakovic just fixed: https://github.com/driftyco/ionic/commit/cac1d4f961137c7fae34adcd3ebc6ba8fecdb0b1
@manucorporat thanks a ton for quick fix, made my day ;-)
I am on the nightly "ionic-angular": "^2.0.0-beta.10-201606302045" and it not solved yet
@cescoferraro the build you mention doesn't contain the fix... it's included in master 2 days later. See: https://github.com/driftyco/ionic/commit/cac1d4f961137c7fae34adcd3ebc6ba8fecdb0b1
@vidakovic OK! How can I get the master from npm then?
@cescoferraro what I did:
Not sure if there is a shorter way to do this, but it's not too bad.
I am having the same issue but when I tried your suggestion I ran into an issue where all components referencing "ionic-angular" complains about it not found. I see this when I try to serve my app using "ionic serve" or even when I try to build my app using "ionic build". Did you run into this by any chance and if so how did you work around it?
@bsakweson be aware that there are some changes (if you are coming from beta 10). E. g. the toast and modal API are used in a slightly different way.
If ionic-angular is not found at all then please double check if you copied your manual build to the correct folder under node_modules in your project directory...
Incredible! Was experiencing a similar issue with ionic-angular beta 10, angular2 rc 4 and angular/forms 0.2.0. Any combination of provideForms() (injected into ionicBootstrap) and ion-range (in any component) would fire exceptions. Got latest rev from master as per comments above, and everything works perfectly now!
Thanks @vidakovic, @manucorporat and @adamdbradley for the great bug fixes and help! Saved me from a ton of headaches!
In addition to @vidakovic's method, if you're using webpack, here's how I was able to use a locally built ionic:
gulp prereleasecd distnpm linknode_modules/ionic-angularnpm link ionic-angularThis way further tweaks to the local ionic build will automatically filter up without requiring constantly cleaning and copying the dist directory. I suspect something similar is possible with browserify, but I don't know.
@vidakovic I followed your steps to generate ionic-angular from master but I can't see package.json in dist folder, any advice?
Another option:
gulp build
and now copy/paste manually the content of /dist inside node_modules/ionic-angular
I was having the same problem with the new forms so I manually updated to master. Now im getting the following errors: "Property 'create' is private and only accessible within class 'Toast' Property 'create' is private and only accessible within class 'Modal'".
Im guessing this has something to do with @vidakovic comment "be aware that there are some changes (if you are coming from beta 10). E. g. the toast and modal API are used in a slightly different way."
What exactly is different about the modal and toast?
My basic toast looks like this.
presentToast(data) {
let toast = Toast.create({
message: data.msg,
duration: 3333
});
if(data.success) {
toast.onDismiss(() => {
this.dismiss(data);
});
}
this.nav.present(toast);
}
I cant seem to find documentation on these changes i'm assuming they will be available with the beta 11 release but if anyone can help that would be great.
@CooleyGit, you instead need to inject ToastController into your component. It has the create() method you're looking for, which returns you a Toast object containing present() and dismiss() methods. Note, the present() is now called from the Toast object, not the NavController as before.
http://ionicframework.com/docs/v2/api/components/toast/ToastController/
Thanks @marpstar that fixed it.
@rapropos I am using webpack, I would be great to use you method to avoid the constant copy/paste. Have not tried this but there is one thing I missed, what do I do with the package.json. Keep it on beta.10 ?
@cescoferraro the gulp prerelease step should create the package.json for the local ionic itself. If you're concerned about the package.json for your app, I don't think it matters: npm should notice that it's a link and not bother you about it.
is it resolved ?
I am having the same issue... getting the master, rebuilding and copying to my project did not resolve the issue. Not sure what I am doing wrong.... Thanks in advance.
Here is the error:
Error: Uncaught (in promise): EXCEPTION: Error in build/pages/login/login.html:19:38
ORIGINAL EXCEPTION: Cannot find control ''
ORIGINAL STACKTRACE:
Error: Cannot find control ''
at new BaseException (http://localhost:8100/build/js/app.bundle.js:3979:23)
at _throwError (http://localhost:8100/build/js/app.bundle.js:41213:11)
at Object.setUpControl (http://localhost:8100/build/js/app.bundle.js:41186:9)
at FormGroupDirective.addControl (http://localhost:8100/build/js/app.bundle.js:40721:18)
at FormControlName.ngOnChanges (http://localhost:8100/build/js/app.bundle.js:40589:32)
at DebugAppView._View_LoginPage0.detectChangesInternal (LoginPage.template.js:497:56)
at DebugAppView.AppView.detectChanges (http://localhost:8100/build/js/app.bundle.js:33861:14)
at DebugAppView.detectChanges (http://localhost:8100/build/js/app.bundle.js:33966:44)
at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:8100/build/js/app.bundle.js:33887:19)
at DebugAppView._View_LoginPage_Host0.detectChangesInternal (LoginPage.template.js:45:8)
ERROR CONTEXT:
[object Object]
Here is the form:
<form [formGroup]="loginForm" (ngSubmit)="login(loginForm.value)">
<ion-item [class.error]="!username.valid && username.touched">
<ion-label>Username:</ion-label>
<ion-input type="text" value="" [formControlName]="username"></ion-input>
</ion-item>
<div *ngIf="username.hasError('required') && username.touched"
class="error-box">* Username is required!</div>
<div *ngIf="username.hasError('minlength') && username.touched"
class="error-box">* Minimum username length is 8!</div>
<div *ngIf="username.hasError('checkFirstCharacterValidator') && username.touched"
class="error-box">* Username cant't start with number!</div>
<div *ngIf="!username.valid && username.touched"
class="error-box">* Invalid username, please reenter.</div>
<ion-item [class.error]="!password.valid && password.touched">
<ion-label>Password:</ion-label>
<ion-input type="password" value="" [formControlName]="password" ></ion-input>
</ion-item>
<div *ngIf="password.hasError('required') && password.touched"
class="error-box">* Password is required</div>
<div *ngIf="password.hasError('minlength') && password.touched"
class="error-box">* Minimum password length is 8!</div>
<div *ngIf="password.hasError('checkFirstCharacterValidator') && password.touched"
class="error-box">* Password cant't start with number!</div>
<br/><br/>
<button clear text-center><span dark>Forgot your password?</span></button>
<br/><br/>
<button type="submit" class="custom-button" [disabled]="!loginForm.valid" block>Submit</button>
</form>
Here is the Typescript
import {Control, ControlGroup} from '@angular/common';
import {REACTIVE_FORM_DIRECTIVES, FORM_DIRECTIVES, FormBuilder, FormControl, FormGroup,
Validators} from '@angular/forms';
....
@Page({
templateUrl: 'build/pages/login/login.html',
directives: [REACTIVE_FORM_DIRECTIVES, FORM_DIRECTIVES]
})
export class LoginPage {
loginForm: FormGroup;
username: FormControl;
password: FormControl;
logo:string;
constructor(public nav: NavController, public events:Events, public formBuilder:FormBuilder, public sessionService:SessionService, public userService:UserService, public customerService:CustomerService, public userCustomerService:UserCustomerService, public userCustomerCatalogService:UserCustomerCatalogService, public global:Global) {
this.loginForm = formBuilder.group({
'username': ['', Validators.compose([Validators.required, Validators.minLength(5)])],
'password': ['', Validators.compose([Validators.required, Validators.minLength(5)])]
})
this.username = this.loginForm['username'];
this.password = this.loginForm['password'];
this.logo = global.getLogo();
}
Edit: solution
Turns out the tutorial pointed by @WHarris22 to replicate the error, is even another way of doing forms, one which I've only seen on that tutorial, even after hours of searching.
So to make it workable based on my example it would be like this
Hope it helps somebody.
HTML
<form [formGroup]="bidForm" (ngSubmit)="onSubmit()"
<ion-card>
<ion-list>
<ion-item>
<ion-label floating job-live>Bid Amount</ion-label>
<input job-live type="number" formControlName="amount"/>
</ion-item>
<ion-row *ngIf="!limit">
<ion-col>
<ion-item cb-primary>
<ion-label cb-primary floating>Hours</ion-label>
<input cb-primary type="number" formControlName="hours"/>
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label cb-primary floating>Minutes</ion-label>
<input cb-primary type="number" formControlName="minutes"/>
</ion-item>
</ion-col>
</ion-row>
<ion-item>
<ion-label cb-primary> No Time Limit ?</ion-label>
<ion-toggle cb-info checked="false" formControlName="limit"></ion-toggle>
</ion-item>
</ion-list>
</ion-card>
<button block secondary type="submit" [disabled]="!bidForm.valid">Place Bid!</button>
</form>
The page.ts
import { Component, OnInit } from '@angular/core';
// its in "forms" not "common"
import { FORM_DIRECTIVES, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ViewController } from 'ionic-angular';
@Component({
templateUrl: 'build/pages/page1.html',
directives: [FORM_DIRECTIVES]
})
export class page1 implements OnInit {
bidForm: FormGroup;
constructor(private _viewCtrl: ViewController,
private _builder: FormBuilder) {
}
ngOnInit(): void {
this.bidForm = this._builder.group({
'amount': [100],
'hours': [1],
'minutes': [null],
'limit': false
});
}
}
Old problem
I'm still having this issue, on Beta-11
I'm getting the error
ORIGINAL EXCEPTION: No value accessor for 'amount'
but it works if I use normal inputs instead of
My .html form
I've commented the toggle since it is not a part of the form
<form [ngFormModel]="bidForm">
<ion-card>
<ion-list>
<ion-item>
<ion-label floating job-live>Bid Amount</ion-label>
<input job-live type="number" ngControl="amount"/>
</ion-item>
<ion-row *ngIf="!limit">
<ion-col>
<ion-item cb-primary>
<ion-label cb-primary floating>Hours</ion-label>
<input cb-primary type="number" ngControl="hours"/>
</ion-item>
</ion-col>
<ion-col>
<ion-item>
<ion-label cb-primary floating>Minutes</ion-label>
<input cb-primary type="number" ngControl="minutes"/>
</ion-item>
</ion-col>
</ion-row>
<!--<ion-item>
<ion-label cb-primary> No Time Limit ?</ion-label>
<ion-toggle cb-info checked="false" [(ngModel)]="limit"></ion-toggle>
</ion-item>-->
</ion-list>
</ion-card>
<!--<button block secondary type="submit" [disabled]="!bidForm.valid">Place Bid!</button>-->
</form>
The page.ts
import { Component, OnInit } from '@angular/core';
import { FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl } from '@angular/common';
import { ViewController } from 'ionic-angular';
@Component({
templateUrl: 'build/pages/page1.html',
directives: [FORM_DIRECTIVES]
})
export class page1 {
bidForm: ControlGroup;
bid: {amount: number; add: {hours: number; minutes: number}} = {amount: 100, add: {hours: 1, minutes: 15}};
// amount: AbstractControl;
// hours: AbstractControl;
// minutes: AbstractControl;
limit: boolean = false;
constructor(private _viewCtrl: ViewController,
private _builder: FormBuilder) {
this.bidForm = this._builder.group({
'amount': [''],
'hours': [''],
'minutes': ['']
});
// this.amount = this.bidForm.controls['amount'];
// this.hours = this.bidForm.controls['hours'];
//
}
and my bootstrap from app.ts
ionicBootstrap(MyApp, [HTTP_PROVIDERS, disableDeprecatedForms(), provideForms()])
need an help
in ionic 2 if i give input as 011 it gives an error of strict mode hexadecimal
but i want it should treat 011=11
not as an hexadecimal
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
Most helpful comment
@cescoferraro what I did:
Not sure if there is a shorter way to do this, but it's not too bad.