0

I am trying to create a dropdown menu with AngularJS. I created a factory (�?disResource’) and use $resource to retrieve data from a database.

Factory:

angular.module('app').factory('disResource', ['$resource', function($resource) {
  return $resource('/api/disciplines/:dis_id', {}, {
    query: {method:'GET', params: {}, isArray:true},
    create: { method: 'POST' },
    show: { method: 'GET' },
    update: { method: 'PUT', params: {dis_id: '@dis_id'}},
    delete: { method: 'DELETE', params: {dis_id: '@dis_id'} }
  });
}]);

Controller:

angular.module("app").controller("AdminDisSearchCtrl", ['$scope', 'disResource', function ($scope, disResource) { 

  disResource.query(function(reply) {
    $scope.results = { disciplines: reply};
  });
}]);

View:

<h2>Select Discipline:</h2>
  <select data-ng-model="filterItem.discipline" data-ng-options="item.dis_name for item in results.disciplines"></select>  

Everything works well, the dropdown is populated with the $resource data and Console.log indicates that everything gets loaded.

console.log($scope):

...
results: Object
disciplines: Array[6]
0: Resource
  $$hashKey: "00F"
  created_at: "2014-03-13 18:59:25"
  dis_id: 1
  dis_name: "AAA"
  updated_at: "2014-03-13 18:59:25"
  __proto__: Resource
1: Resource
...

However, the dropdown shows a blank space. When I try to specify the default dropdown item in the controller

$scope.filterItem = {
  discipline: $scope.results.disciplines[0]    
};

I receive a Console Error: TypeError: Cannot read property 'disciplines' of undefined

When I hardcode the data into the controller, everything works:

$scope.results = {
  disciplines: [
   { dis_id:1, dis_name:'AAA' },
   { dis_id:2, dis_name:'BBB' }
  ]
};

$scope.filterItem = {
  discipline: $scope.results.disciplines[0]
};

console.log($scope):

...
results: Object
  disciplines: Array[2]
  0: Object
    $$hashKey: "007"
    dis_id: 1 
    dis_name: "AAA"
    __proto__: Object
  1: Object
  ...

Question: Why can't I set the default drop-down option when I retrieve the data from the database?

2
  • 1
    The query call happens async so the function that populates the scope object doesn't occur until after you try to access $scope.results.disciplines hence the TypeError, you may be able to move the code that populates discipline into the callback function for the query call. Commented Mar 20, 2014 at 18:38
  • Thanks, @shaunhusain, moving the code into the callback function solved it! disResource.query(function(data){ $scope.disciplines = data; $scope.filterItem = { discipline: $scope.disciplines[0] }; }, function(err){ alert('request failed'); }); Please turn your comment into an answer if you would like me to select it as the accepted answer. Commented Mar 21, 2014 at 10:27

1 Answer 1

1

Posting my comment as an answer as requested since it solved the problem.

All of the calls on a $resource or via the $http service object are done asynchronously since they are network calls and it's indeterminate how long it will take to get a response (if it were synchronous no other code would execute while the request was being made which is undesirable).

The fix is to just move the code that is expecting to use the data for initialization into the callback for the async function call. The callback is called as soon as response from the server is retrieved (after running the response through any interceptors you define)

Long story short in this case move this bit of code

$scope.filterItem = {
  discipline: $scope.results.disciplines[0]
};

Into the callback after the $scope.results has been assigned.

If you use $http (like $http.get(url) or $http.post(data,url)) the calls return an HTTPPromise so you can use success and error handler functions on the promise to get the data.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.