1

I have an issue while populating data in drop down component. When I do it with dummy JSON data (like in the comments), then all works fine.

GET request service pulls necessary data, then I'm assigning it's response to appropriate variable. Get service and drop down component are placed in another View component.

No error message in the console... what do I miss here?

GET requests service:

(function () {
    "use strict";
    angular.module('app').factory('GetService', function ($http) {
        return{
            get: function (uri, config) {
                $http.get(uri, config).
                    then(function(response) {
                        return response.data;
                    });
            }
        }
    });
}());

Drop-down component that accepts JSON data.

(function () {
"use strict";

var module = angular.module("app");
module.component("dropDown", {
    template: 
    <div class="input-group">
        <span class="input-group-addon">{{vm.placeholder}}</span>
        <select class="form-control"
            ng-model="vm.selectedItem"
            ng-options="option.name for option in vm.items"></select>
    </div>,
    controllerAs: "vm",
    bindings: {
        placeholder: '@',
        itemlist: '='
    },
    controller: function() {
        var vm = this;
        vm.items = vm.itemlist;
        vm.selectedItem = vm.itemlist[0];
    }
});
})(); 

View component:

(function () {
    "use strict";
    var module = angular.module('app');

    function controller(GetService) {
        var vm = this;
        vm.$onInit = function () {              
            vm.doprdown1url = "/Controller/Action1";
            vm.doprdown2url = "/Controller/Action2";
            vm.dd1List = [];
            vm.dd2List = [];
            GetService.get(vm.doprdown1url, null).then(function (data) {
                vm.dd1List = JSON.parse(data.data);
            });
            GetService.get(vm.doprdown2url, null).then(function (data) {
                vm.dd2List = JSON.parse(data.data);
            });
            //vm.dd1List = [{
            //    id: 0,
            //    name: 'Arm'
            //}, {
            //    id: 1,
            //    name: 'Leg'
            //}, {
            //    id: 2,
            //    name: 'Hand'
            //}];

            //vm.dd2List = [{
            //    id: 0,
            //    name: 'Eye'
            //}, {
            //    id: 1,
            //    name: 'Nose'
            //}, {
            //    id: 2,
            //    name: 'Ear'
            //}];
        }
    }

    module.component("view1", {
        template: 
        <p>
           <drop-down placeholder="Title" itemlist="vm.dd1List"></drop-down>
           <drop-down placeholder="Title2" itemlist="vm.dd2List"></drop-down>
        </p>,
        controllerAs: "vm",
        controller: ["$http", controller]
    });
}());
Rob
  • 14,746
  • 28
  • 47
  • 65
Maxim Hash
  • 405
  • 4
  • 19
  • You're returning `response.data` from your factory method, but then you are using `JSON.parse(data.data)` in your controller. I think you want to use `JSON.parse(data)` instead. – Lex Jul 06 '16 at 22:54

1 Answers1

1

It's because all your templates are loaded before the service returns any data. The ugly solution is to use timeout to make sure the problem comes from there. (see snippet below, you need to wait 5 seconds to see the result)

The better solution is to call the service from the child component through the require option

function GetService($http) {
  return{
    get: function (uri, config) {
      $http.get(uri, config).
      then(function(response) {
        return response.data;
      }, function(response) {
        return response;
      });
    }
  }
};
var dropDown = {
    template: `
    <div class="input-group">
        <span class="input-group-addon">{{$ctrl.placeholder}}</span>
        <select class="form-control"
            ng-model="$ctrl.selectedItem"
            ng-options="option.name for option in $ctrl.items"></select>
    </div>`,
    bindings: {
        placeholder: '@',
        itemlist: '='
    },
    controller: function($timeout) {
        var vm = this;
        $timeout(function() {
          console.log(vm.itemlist);
          vm.items = vm.itemlist;
          vm.selectedItem = vm.itemlist[0];
        }, 5000);
    }
};
function controller(GetService) {
  var vm = this;
  vm.$onInit = function () {              
    vm.doprdown1url = "https://randomuser.me/api/";
    vm.doprdown2url = "https://randomuser.me/api/";
    vm.dd1List = [];
    vm.dd2List = [];
    GetService.get(vm.doprdown1url, null).then(function (data) {
      console.log(data.data.info.seed);
      vm.dd1List = [{id: 1, name: data.data.info.seed}];
    });
    GetService.get(vm.doprdown2url, null).then(function (data) {
      console.log(data.data.info.seed);
      vm.dd2List = [{id: 1, name: data.data.info.seed}];
    });
  }
};

var view1 = {
  template: `
  <p>
  <drop-down placeholder="Title" itemlist="$ctrl.dd1List"></drop-down>
  <drop-down placeholder="Title2" itemlist="$ctrl.dd2List"></drop-down>
  </p>`,
  controller: ["$http", controller]
};

angular.module('myApp', []);
angular
    .module('myApp')
    .factory('GetService', GetService)
    .component('dropDown', dropDown)
    .component('view1', view1);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<div ng-app="myApp">
    <view1></view1>
</div>
gyc
  • 4,300
  • 5
  • 32
  • 54
  • Thanks! The "ugly" solution confirmed the problem! Now I will use require to do it proper way... I'm surprised that this issue was never mentioned before in any documentation/tutorial I have been reading before... is my approach unusual, am I breaking the patterns? – Maxim Hash Jul 07 '16 at 14:20
  • @MaximHash actually the problem comes from the fact you are copying itemlist into another variable which breaks the binding. ng-model="$ctrl.itemlist[0]" and ng-options="option.name for option in $ctrl.itemlist"> works. you can remove your dropDown controller code. Also you can take a look at lifecycle hooks https://docs.angularjs.org/api/ng/service/$compile#life-cycle-hooks – gyc Jul 07 '16 at 22:31
  • I finally ended up with solution presented in the link, just in case if somebody need it: http://stackoverflow.com/a/28766260/3966640 – Maxim Hash Jul 27 '16 at 22:49