Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Ionic2 beta 10 ionic form elements do not work with @angular/forms #7125

Closed
WHarris22 opened this issue Jun 29, 2016 · 30 comments
Closed
Assignees
Milestone

Comments

@WHarris22
Copy link

WHarris22 commented Jun 29, 2016

Short description of the problem:

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" />

What behavior are you expecting?

Ionic form elements; ion-input, ion-textarea, ion-select etc should all work with the new @angular/forms module.

Steps to reproduce:

  1. Start a new Ionic app using beta 10
  2. Add the @angular/forms module to the app
  3. In the app.ts file import the following import {disableDeprecatedForms, provideForms} from '@angular/forms';
  4. And then add the two imports to the ionicBootstrap like this ionicBootstrap(MyApp, [ disableDeprecatedForms(), provideForms() ]);
  5. Now on another page create a form using Ionic inputs and the Form Builder part of this tutorial

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

@WHarris22 WHarris22 changed the title bug: beta 10 ionic form elements do not work with @angular/forms bug: Ionic2 beta 10 ionic form elements do not work with @angular/forms Jun 29, 2016
@jgw96 jgw96 added the v2 label Jun 29, 2016
@jgw96
Copy link
Contributor

jgw96 commented Jun 29, 2016

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: #6580

@adamdbradley adamdbradley self-assigned this Jun 29, 2016
@adamdbradley adamdbradley added this to the 2.0.0-beta.11 milestone Jun 29, 2016
@jgw96
Copy link
Contributor

jgw96 commented Jun 29, 2016

This may be related to(not 100% on that): #7010

@rapropos
Copy link
Contributor

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".

@jgw96
Copy link
Contributor

jgw96 commented Jun 30, 2016

@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!

@kokokenada
Copy link

BTW - will Ionic be supporting Angular built in validators like required, minlength, maxlength, pattern?

@rapropos
Copy link
Contributor

rapropos commented Jul 1, 2016

This is fixed for me (with ion-checkbox) as of this commit.

@adamdbradley
Copy link
Contributor

Yup, this should be closed with this commit: 4d56219

@vidakovic
Copy link

@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'.

manucorporat added a commit that referenced this issue Jul 2, 2016
@manucorporat
Copy link
Contributor

@vidakovic just fixed: cac1d4f

@vidakovic
Copy link

@manucorporat thanks a ton for quick fix, made my day ;-)

@cescoferraro
Copy link

I am on the nightly "ionic-angular": "^2.0.0-beta.10-201606302045" and it not solved yet

@vidakovic
Copy link

@cescoferraro the build you mention doesn't contain the fix... it's included in master 2 days later. See: cac1d4f

@cescoferraro
Copy link

@vidakovic OK! How can I get the master from npm then?

@vidakovic
Copy link

@cescoferraro what I did:

  • checkout the master branch with git
  • build: gulp build --typecheck
  • delete [YOURPROJECT]/node_modules/ionic-angular
  • copy the content of "dist" folder to [YOURPROJECT]/node_modules/ionic-angular

Not sure if there is a shorter way to do this, but it's not too bad.

@bsakweson
Copy link

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?

@vidakovic
Copy link

@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...

@yrefaeli
Copy link

yrefaeli commented Jul 6, 2016

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!

@rapropos
Copy link
Contributor

rapropos commented Jul 6, 2016

In addition to @vidakovic's method, if you're using webpack, here's how I was able to use a locally built ionic:

  • check out with git
  • gulp prerelease
  • cd dist
  • npm link
  • go to app project directory
  • clear out node_modules/ionic-angular
  • add aliases described in this issue to webpack configuration
  • npm link ionic-angular

This 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.

@guillenotfound
Copy link
Contributor

@vidakovic I followed your steps to generate ionic-angular from master but I can't see package.json in dist folder, any advice?

@manucorporat
Copy link
Contributor

manucorporat commented Jul 6, 2016

Another option:

gulp build

and now copy/paste manually the content of /dist inside node_modules/ionic-angular

@CooleyGit
Copy link

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.

@marpstar
Copy link
Contributor

marpstar commented Jul 14, 2016

@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/

@CooleyGit
Copy link

Thanks @marpstar that fixed it.

@cescoferraro
Copy link

@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 ?

@rapropos
Copy link
Contributor

@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.

@tripathi-swapnil
Copy link

is it resolved ?

@donaldhook
Copy link

donaldhook commented Aug 19, 2016

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();
  }

@p-sebastian
Copy link

p-sebastian commented Sep 11, 2016

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()])

@Raviraj20
Copy link

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

@ionitron-bot
Copy link

ionitron-bot bot commented Sep 4, 2018

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.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Sep 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests