0

I'm trying to share a $http request and return it's value. But it seems like it's 'deferred' and won't set the value.

For this example, I have 2 select box choices of cars. So the controller loads the cars from cars.json whose value is assigned to $scope.cars:

app.controller('MainCtrl', function($scope, $http, LoadCars) {

  LoadCars.async().success(function(data) {
    $scope.cars = data;
    $scope.carA = $scope.carB = data[0];
    $scope.carAChanged();
    $scope.carBChanged();
  });

  $scope.carAChanged = function() {
    $scope.modelsA = $scope.carModels($scope.carA.c);
  }

  $scope.carBChanged = function() {
    $scope.modelsB = $scope.carModels($scope.carB.c);
  }

  $scope.carModels = function(code) {
        var promise = $http.get(code + '.json')
            .success(function(data) {
                //$scope.modelsA = data;
                return data;
            });
        return promise;
    }  
});

HTML:

<fieldset>
  <legend>Choice 1</legend>
  <div><select ng-model="carA" ng-options="c.name for c in cars" ng-change="carAChanged()"></select></div>
  <div><select ng-model="modelA" ng-options="m.c for m in modelsA"></select></div>
</fieldset>

<fieldset>
  <legend>Choice 2</legend>
  <div><select ng-model="carB" ng-options="c.name for c in cars" ng-change="carBChanged()"></select></div>
  <div><select ng-model="modelB" ng-options="m.c for m in modelsB"></select></div>
</fieldset>

Plunker: http://plnkr.co/edit/5CFFGJ?p=preview

If i uncomment the line inside $scope.carModels(), $scope.modelsA loads up fine. But I want the value to return because I need to set modelsB as well separately.

What am I doing wrong? And what's the correct way to achieve this?

1 Answer 1

1

Update

Based on your feedback, it appears as though you are looking for something a little more like this (http://plnkr.co/edit/WpCuMA?p=preview):

<body ng-controller="MainCtrl">
    <car-select ng-model="makes" data-label="Choice One"></car-select>
    <car-select ng-model="makes" data-label="Choice Two"></car-select>
    <car-select ng-model="makes" data-label="Choice Three"></car-select>
    <car-select ng-model="makes" data-label="Choice Four"></car-select>
    <car-select ng-model="makes" data-label="Choice Five"></car-select>
    <car-select ng-model="makes" data-label="Choice Six"></car-select>
</body>

var app = angular.module('plunker', []);

app.service('Car', function($http, $q) {
    this.getMakes = function(){
    return $http.get('cars.json');
    }
  this.getModels = function(code){
    return $http.get(code + '.json');
  }
});

app.controller('MainCtrl', function($scope, Car) {
  Car.getMakes().success(function(makes){
    $scope.makes = makes;
  });
});

app.directive('carSelect', function($log, Car){
  return {
    restrict: 'E',
    scope: {
      label: "@label",
      makes: "=ngModel"
    },
    replace: true,
    template: '<fieldset><legend>{{label}}</legend>' +
    '<div><select ng-model="make" ng-options="make.name for make in makes" ng-change="makeChanged(make.c)"></select></div>' +
    '<div><select ng-model="model" ng-options="model.c for model in models"></select></div></fieldset>',
    link: function(scope, elm, attr){
      scope.makeChanged = function(code){
        Car.getModels(code).success(function(models){
          scope.models = models;
        });
      }
    }
  }
});

Old way...

http://plnkr.co/edit/wg01Wt?p=preview

var app = angular.module('plunker', []);

app.service('Cars', function($http, $q) {
    this.getMakes = function() {
        return $http.get('cars.json');
    }
    this.getModels = function(code) {
        return $http.get(code + '.json');
    }
});

app.controller('MainCtrl', function($scope, Cars) {

    Cars.getMakes().success(function(makes) {
        $scope.cars = makes;
    });

    $scope.carAChanged = function() {
        Cars.getModels($scope.carA.c).success(function(cars) {
            $scope.modelsA = cars;
        });
    }

    $scope.carBChanged = function() {
        Cars.getModels($scope.carB.c).success(function(cars) {
            $scope.modelsB = cars;
        });
    }
});
Sign up to request clarification or add additional context in comments.

3 Comments

This is similar to what I had originally. But I thought there'd be a way to avoid writing the same $http statement twice.
I updated the service a bit but what you really need is a directive for the drop-downs.
The directive approach should make things easier to reuse.

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.