Google analytics code

Monday, July 28, 2014

Angular: Form element not attaching to $scope

I'm well into a redesign using AngularJS as my front-end framework. After a small learning period I'm in love. It's a fantastic way to tie your UI to your backend. That said there is still some work to be done.

I'm breaking my project into modules that are included with the ng-include tag. This helps shrink the code on the page into manageable chunks. It nice when you're using a very verbose framework like Bootstrap.

All of my forms are wired up using Angular's form validation. Once again this is fantastic. Being able to watch the inputs in real time and display helpful errors is great. I ran into an issue trying to reuse a form after I've removed it from the users view.

<form name="createUser">
    <input name="name" ng-model="formObj.name" />
    <input name="email" ng-model="formObj.email" />
</form>

I should be able to access the form in my angular in this fashion.

// This will reset any validation errors on the form
$scope.createUser.$setPristine();

This wasn't working for me and I spent a lot of time trying to figure out why. Here is how my code looked.

<div ng-controller=“controllerName”>
    <div ng-include=“ ‘path-to-the-template’ ”></div>
</div>

<!—- Inside path-to-the-template -—>
<form name="createUser">
    <input name="name" ng-model="formObj.name" />
    <input name="email" ng-model="formObj.email" />
</form>

One thing to consider is when Angular is starting up the controller code the form isn't attached yet. When you click the button that submits the form it will be attached by that time. I was still unable to access the form element.

Update

I submitted this as a bug to the git repo and got a response very quickly. That team is really on top of things. Turns out when you use ng-include it creates a new scope var. This is how the setup should look.

<!—- The vars should live in the controller. I placed them here for the example. -—>
<div ng-controller=“controllerName” ng-init="form={}; model={}" >
    <div ng-include=“ ‘path-to-the-template’ ”></div>
</div>

<!—- Inside path-to-the-template -—>
<form name="form.createUser">
    <input name="name" ng-model="model.name" />
    <input name="email" ng-model="model.email" />
</form>

Now the include can reference the variables from the parent scope. The form and it's input should now be accessible.