2
votes

I'm building a form for a mobile app.

I have two sets of radio-groups using ion-radio. One to select sex of the fish and one to select the fate of the fish after successful catch. I can't get these radio inputs to work with formBuilder.

I get two error messages refenrencing lines 113 and 114 in CatchPage.html. Both are identical except for line number so I'll only put one here.

CatchesPage.html:113 ERROR Error: No value accessor for form control with name: 'catchSex'
    at _throwError (forms.es5.js:1830)
    at setUpControl (forms.es5.js:1740)
    at FormGroupDirective.addControl (forms.es5.js:4711)
    at FormControlName._setUpControl (forms.es5.js:5299)
    at FormControlName.ngOnChanges (forms.es5.js:5217)
    at checkAndUpdateDirectiveInline (core.es5.js:10790)
    at checkAndUpdateNodeInline (core.es5.js:12216)
    at checkAndUpdateNode (core.es5.js:12155)
    at debugCheckAndUpdateNode (core.es5.js:12858)
    at debugCheckDirectivesFn (core.es5.js:12799)

after these errors I get

ERROR Error: Uncaught (in promise): Error: No value accessor for form control with name: 'catchSex'
Error: No value accessor for form control with name: 'catchSex'
    at _throwError (forms.es5.js:1830)
    at setUpControl (forms.es5.js:1740)
    at FormGroupDirective.addControl (forms.es5.js:4711)
    at FormControlName._setUpControl (forms.es5.js:5299)
    at FormControlName.ngOnChanges (forms.es5.js:5217)
    at checkAndUpdateDirectiveInline (core.es5.js:10790)
    at checkAndUpdateNodeInline (core.es5.js:12216)
    at checkAndUpdateNode (core.es5.js:12155)
    at debugCheckAndUpdateNode (core.es5.js:12858)
    at debugCheckDirectivesFn (core.es5.js:12799)
    at _throwError (forms.es5.js:1830)
    at setUpControl (forms.es5.js:1740)
    at FormGroupDirective.addControl (forms.es5.js:4711)
    at FormControlName._setUpControl (forms.es5.js:5299)
    at FormControlName.ngOnChanges (forms.es5.js:5217)
    at checkAndUpdateDirectiveInline (core.es5.js:10790)
    at checkAndUpdateNodeInline (core.es5.js:12216)
    at checkAndUpdateNode (core.es5.js:12155)
    at debugCheckAndUpdateNode (core.es5.js:12858)
    at debugCheckDirectivesFn (core.es5.js:12799)
    at c (polyfills.js:3)
    at Object.reject (polyfills.js:3)
    at Tab.NavControllerBase._fireError (nav-controller-base.js:322)
    at Tab.NavControllerBase._failed (nav-controller-base.js:310)
    at nav-controller-base.js:365
    at t.invoke (polyfills.js:3)
    at Object.onInvoke (core.es5.js:4128)
    at t.invoke (polyfills.js:3)
    at r.run (polyfills.js:3)
    at polyfills.js:3

I also get similar error messages for my 'catchFate' radio-group.

HTML snippet from catches.html. Entire .html page can be seen here https://pastebin.com/vKW2vp7F.

  <ion-row radio-group [(ngModel)]="catchSexSelection" [ngModelOptions]="{standalone: true}">
    <ion-item no-lines>
      <h2>Sex</h2>
    </ion-item>
    <!--FISH SEX-->
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="male"></ion-icon> Male</ion-label>
        <ion-radio value="male" formControlName="catchSex"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="female"></ion-icon> Female</ion-label>
        <ion-radio value="female" formControlName="catchSex"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>Unknown</ion-label>
        <ion-radio value="unknown" formControlName="catchSex"></ion-radio>
      </ion-item>
    </ion-col>
  </ion-row>

The entire form with all fields and radio selectors is inside one formGroup.

<form [formGroup]="addCatchForm" (submit)="addToDb()" novalidate>
...Entire form...    
</form>

Relevant parts from catches.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, AlertController } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AuthProvider } from '../../providers/auth/auth';
import { ProfileProvider } from '../../providers/profile/profile';
import * as moment from 'moment';

@IonicPage(
  { name: 'CatchesPage' }
)
@Component({
  selector: 'page-catches',
  templateUrl: 'catches.html',
})
export class CatchesPage {
  addCatchForm: FormGroup;

  userProfile: any;
  userName: string;

  catchSpecies: string;
  catchSexSelection: string;
  catchWeight: number = 0;
  catchLength: number = 0;
  catchGirth: number = 0;
  catchFate: string;

  lureType: string;
  fate: boolean;

  currentDate: string = moment().format();


  constructor(public navCtrl: NavController, public navParams: NavParams, public authProvider: AuthProvider, public profileProvider: ProfileProvider, private alertCtrl: AlertController, public formBuilder: FormBuilder) {

    this.addCatchForm = formBuilder.group({
      catchCaughtBy: ['', Validators.compose([Validators.required])],
      catchDate: ['', Validators.compose([Validators.required])],
      catchLocation: ['', Validators.compose([Validators.required])],
      catchLocationDesc: [''],
      catchSpecies: [''],
      catchSexSelection: [''],
      catchWeight: [''],
      catchLength: [''],
      catchGirth: [''],
      lureModel: [''],
      lureType: [''],
      lureTechnique: [''],
      catchFate: ['']
    });

  }

Ionic/Angular version

Ionic Framework: 3.3.0
Ionic App Scripts: 1.3.7
Angular Core: ^4.1.2
Angular Compiler CLI: ^4.1.2
Node: 7.10.0
OS Platform: Windows 10
Navigator Platform: Win32
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36

I don't understand why these errors occur. I've defined value attribute inside for each selection and each has the same formControlName. Each is inside the same radio-group.

My login page uses formBuilder and it works fine, but radio inputs are giving me a headache.

I decided to user formBuilder because I might want to use some kind of validation in the future. I just want to get the functionality working and send the data to firebase using addToDb method before going too deep into validation.

What should I do?

2

2 Answers

5
votes

Try binding the control to the group instead:

<ion-row radio-group  formControlName="catchSex" [(ngModel)]="catchSexSelection" [ngModelOptions]="{standalone: true}">
    <ion-item no-lines>
      <h2>Sex</h2>
    </ion-item>
    <!--FISH SEX-->
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="male"></ion-icon> Male</ion-label>
        <ion-radio value="male"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="female"></ion-icon> Female</ion-label>
        <ion-radio value="female"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>Unknown</ion-label>
        <ion-radio value="unknown"></ion-radio>
      </ion-item>
    </ion-col>
  </ion-row>
1
votes

First of all don't use Reactive Form and Template Driven Form together.

You can also use as following to avoid the error Error: No value accessor for form control with name: 'catchSex'

<ion-row radio-group ngDefaultControl formControlName="catchSex">
    <ion-item no-lines>
      <h2>Sex</h2>
    </ion-item>
    <!--FISH SEX-->
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="male"></ion-icon> Male</ion-label>
        <ion-radio value="male"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>
          <ion-icon name="female"></ion-icon> Female</ion-label>
        <ion-radio value="female"></ion-radio>
      </ion-item>
    </ion-col>
    <ion-col col-4>
      <ion-item no-lines>
        <ion-label>Unknown</ion-label>
        <ion-radio value="unknown"></ion-radio>
      </ion-item>
    </ion-col>
  </ion-row>

ngDefaultControl is to be added to avoid that error.

I had resolved the same way.