Simple AngularJS Form is undefined in Scope Simple AngularJS Form is undefined in Scope angularjs angularjs

Simple AngularJS Form is undefined in Scope


A good way to perform this without using watch (which is a bit overkill) is to define an object in the scope into which you will register the form.

HTML

<div id="mainContainer" ng-app="angularTest" ng-controller="MainCtrl">    <h1>The Form</h1>    <form name="form.theForm">        <input name="myName" type="text" ng-model="model.name" />        <input type="button" value="Here the scope" ng-click="display()"/>        <input name="submit" type="submit" />    </form></div>

JS

var app = angular.module('angularTest', []);app.controller('MainCtrl', ['$scope', function($scope) {    $scope.model = { name: 'Model Name' };    $scope.form = {};    $scope.display = function () {        console.log($scope.form.theForm);    }}]);


The form only registers itself with the $scope of the controller after the controller has initially run. Therefore the console.log($scope.theForm) will return undefined even if everything is setup correctly.

In your example to react to the presence of theForm, you can setup a watcher on theForm to set debug text depending its presence:

$scope.$watch('theForm', function(theForm) {    if(theForm) {         $scope.formDebugText = 'Form in Scope';    }    else {        $scope.formDebugText = 'Form is Undefined';    }        });

which can be seen in action at http://jsfiddle.net/9k2Jk/1/


What fixed it for me was to use a parent object on the $scope.

In the controller:

$scope.forms = {};$scope.registerUser = function registerUser() {    if ($scope.forms.userForm.$valid) {        alert('submit');    }};

In the template:

<form name="forms.userForm" ng-submit="registerUser()">

The reason:

If you use <form name="userForm"... instead of <form name="forms.userForm"... it attaches the form to a child scope, but because $scopes use prototypical inheritance, as soon as I declared an empty object literal on the original $scope the form was attached to it instead.