Change in data made by $http inside a factory is not reflected to the DOM

76 views Asked by At

I'm trying to create a dynamic form based on an object. For example: I'd like that generated select boxes will contain options if given, otherwise a factory will fetch them using ajax, something like this:

Markup:

<select ng-repeat="select in selects"
        ng-init="options = refactor.options(select)"
        ng-options="option in options">
</select>

Controller:

myApp.controller('MyCtrl', function($scope, refactor) {
   $scope.refactor = refactor;
   $scope.selects = [
          { text: "Country", value="chosen.country", options=["France", "England"] },
          { text: "Gender", value="chosen.gender", options="/gender" }
        ]
});

Factory:

myApp.factory('refactor', function($scope, $http) {
  return {
    options: function(select) {
      if(typeof(select.options) === 'object') { return select.options };
      // otherwise assume select.options is 
      // a path to fetch options by ajax:
      $http.get(select.options).success(function(data) {
         select.options = data; // data == ['male', 'female']
      });

      return []; // placeholder until promise is fulfilled
    }
  }
})

The data ( $scope.selects ) gets updated as expected, yet the DOM is not, which probably means refactor.options() is not being invoked again in response to the change. I tried to force an update by passing the scope object to the factory and invoke $apply on it, but it doesn't work.

What am I missing?

2

There are 2 answers

4
Pankaj Parkar On

You need to use ng-init="data = refactor.options(select)" so after getting data from ajax data would be filled up with options then you could use ng-options as instead of ng-options="option in data.options".

Markup

<select ng-repeat="select in selects"
    ng-init="data = refactor.options(select)"
    ng-options="option in data.options">
</select>
0
Abdul23 On

You should try this

myApp.factory('refactor', function($scope, $http) {

return {
    options: function(select) {
               var menuItems={
                     options:[]
                  }

                if(typeof(select.options) === 'object'){
                   menuItems.options=select.options
                };

               // otherwise assume select.options is 
               // a path to fetch options by ajax:

               $http.get(select.options).success(function(data) {
                    select.options = data; 
                    menuItems.options=data;// data == ['male', 'female']
               });

               return menuItems; // placeholder until promise is fulfilled
            }
       }
});

Then inside your view it should go like this

<select ng-repeat="select in selects"
    ng-init="menuItems= refactor.options(select)"
    ng-options="option in menuItems.options">
</select>