AngularJS pass $resource as a directive parameter
angularjs, directive
Solution
Here we simulated async call factory by using wrapper with `$q`.
- We changed `modelReflist` to `modelRefList`
- added `ng-model="item"` to template
HTML
<div ng-controller="TestCtrl">
<input-select model-ref-list="countryList"></input-select>
</div>
JS
var App = angular.module('myModule', ['ngResource']);
App.controller(
'TestCtrl', [
'$scope', 'countriesFactory',
function ($scope, countriesFactory) {
/* Call API */
countriesFactory.resourceAPICall().then(function (data) {
$scope.countryList = data.country;
console.log($scope.countryList);
});
}])
App.$inject = ['$scope', 'countriesFactory'];
App.directive("inputSelect", function () {
var Template = '<select ng-model="item" ng-options="item.label as item.label for item in modelRefList" required></select>';
return {
restrict: 'EA',
template: Template,
scope: {
modelRefList: '='
},
link: function (scope) {
console.log(scope.countryList);
}
};
});
App.factory('countriesFactory', ['$resource', '$q', function ($resource, $q) {
var data = {
"country": [{
"code": "ABW",
"label": "Aruba"
}, {
"code": "AFG",
"label": "Afghanistan"
}, {
"code": "AGO",
"label": "Angola"
}]
};
var factory = {
resourceAPICall: function () {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Demo Fiddle
Problem
I have just came up with a directive that loads a dropdown box according to a list coming from an API call ($resource). Controller: ``` App.controller( 'TestCtrl', [ '$scope', 'countriesFactory', function($scope, countriesFactory){ /* Call API */ countriesFactory().then(function(data){ $scope.countryList = data; }); }]) ``` The API call returns: ``` {"country":[{"code":"ABW","label":"Aruba"},{"code":"AFG","label":"Afghanistan"},{"code":"AGO","label":"Angola"}]} ``` Template: ``` <input-select model-ref-list="countryList"></input-select> ``` Directive: ``` App .directive("inputSelect" , function() { var Template = '<select ng-options="item.label for item in modelRefList" required></select>'; return { restrict: 'EA', template: Template, scope: { modelRefList: '=' }, link: function(scope){ console.log(scope.modelRefList); } }; } ); ``` First of all: I simplified a lot the overall issue, so that it looks that the directive is completely overkill in that situation, but in the end, it is not :D. Problem: My console.log is always undefined. I made a bit of research and realized that I needed to play with promises to wait for my country list to appear to be actually given to the directive. So I tried modifying my controller and not use the result of the API call promise, but directly the resource itself: New Controller: ``` App.controller( 'TestCtrl', [ '$scope', 'countriesFactory', function($scope, countriesFactory){ /* Call API */ $scope.countryList = resourceAPICall(); }]) ``` But still undefined :/. How can I pass direclty the resource (containing the promise I can then use to defer the load of the select) to the directive? SOLUTION FOR ANGULARJS 1.2: Directive: ``` App .directive("inputSelect" , function() { var Template = '<select ng-options="item.label for item in modelRefList" required></select>'; return { restrict: 'EA', template: Template, scope: { modelRefList: '=' }, link: function(scope){ scope.modelRefList.$promise.then(function(data){ console.log(data); } }; } ); ``` To pass a API call result to a directive, you need to pass its resource and play with its promise inside the directive itself. Thanks everybody for the help.