Sunday, December 1, 2013

AngularJS and select statements using resources

I would expect from a good framework like AngularJS that it integrates their methods to play together nicely to solve problems such as the issue with the select statement that only supports referential equality which is not working with resources ($resource) as data source. In the edit case where an object in the ng-model is matched to the resource object it will fail. It took me about 4 hours analyze the problem and then find the ngyn select directive that solves the problem with an own select directive. I'd like to thank the authors for this nice plugin and hope it will find it's way in to the AngularJS code eventually.

Select Extensions

The AngularJS select directive lacks the capability to select an existing option based on anything other than referential equality. The ngynSelectKey module extends select with the capability to specify how items should be compared. This makes it trivial to match an item in the select list with a value being returned, for example from a query.

Usage is simple, just supply a value within a key attribute, this will typically be a property name but it can be anything which will resolve using $scope.$eval(), such as a function on each attribute.

HTML
<select ng-model="user.role" 
        ng-options="r.name for r in user.availableRoles" 
        key="id">
</select>
JavaScript
  $scope.user = {};
  $scope.user.role = { id: 1, name: 'Administrator' };
  $scope.user.availableRoles = Roles.query();
  • You can find the description here
  • You can find the source here

Integrate the plugin

To integrate the plugin I have downloaded the select-key.js file and added it to my lib directory in which also the AngularJS libraries are located.

Then I added the file to my index.html page.

<script src="../lib/angular120/angular.js"></script>
<script src="../lib/angular120/angular-route.js"></script>
<script src="../lib/angular120/angular-resource.js"></script>
<script src="../lib/ngyn/select-key.js"></script>

And as last step added the module in to my app (app.js) in my case.

angular.module('myApp', ['ngRoute',
        'ngynSelectKey',
        'errorHelper',
        'formHelper',
        'fileHelper',
        'eaValidators',
        'user',
        'vendor',
        'card'])