sitesbyjoe
sitesbyjoe

Reputation: 1861

Angular: Passing data back to my controller from a factory ajax call

I've been playing with Angular and I've moved from working with local data (which seems to work fine) to trying to populate my view from an ajax call in my factory.

Here's the code:

    <html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js"></script>
</head>
<body>
<div ng-app="testApp">
  <h2>Get data using a Factory</h2>
    <div ng-controller="simpleController">

    <input type="text" placeholder="Filter" ng-model="name">

    <ul>
      <li ng-repeat="person in family | filter:name">[{{$index + 1}}] {{person.name}} - {{person.age}}</li>
    </ul>

  </div>
</div>
<script>
// our very, very simple controller - on the page itself
var testApp = angular.module('testApp', []);

testApp.factory('simpleFactory', function($http) {
  var family = [
    {name: 'Joe', age: 40},
    {name: 'Maryellen', age: 37},
    {name: 'Isaac', age: 12},
    {name: 'Emilie-Alice', age: 14}
  ];

  var factory = {};
  factory.getFamily = function() {
    return family;
  }

  factory.getFamily2 = function() {
    $http.get('/family.json').then(function(result) {
      family = result.data;
      console.log(family); // I see the objects! 
      return family; // this doesn't return the data like getFamily() does - why???
    });
  }

  return factory;
});

testApp.controller('simpleController', function($scope, simpleFactory) {
  $scope.family = [];

  init();

  function init() {
    $scope.family = simpleFactory.getFamily2();
  }
});
</script>
</body>
</html>

Everything seems okay, I can see the json data in my console log, but "return family" doesn't get the data to $scope.family

What am I missing? I know it has to be something simple.

Thanks!

Upvotes: 2

Views: 2610

Answers (3)

jjalonso
jjalonso

Reputation: 688

The answer of sitesbyjoe is fine, but... you don't need the first assignation in controller (line 2 of 2nd block code), only calling to the function and assign a value inside is enogh

Factory

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      return family;
    });
  }

In Controller

 function init() {
    simpleFactory.getFamily2().then(function(data) {
        $scope.family = data;
    });
  }

Upvotes: 2

sitesbyjoe
sitesbyjoe

Reputation: 1861

FYI - What I ended up changing in the factory:

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      return family;
    });
  }

and in the controller:

function init() {
    $scope.family = simpleFactory.getFamily2().then(function(data) {
        $scope.family = data;
    });
  }

With these changes in place I get the remote data, the view filtering works fine, and all is well.

Upvotes: 0

TrazeK
TrazeK

Reputation: 838

To completely abstract the data handling into the factory, you can both return the promise from $http and leave the return inside the .then():

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      console.log(family); // I see the objects! 
      return family; // this doesn't return the data like getFamily() does - why???
    });
  }

function init() {
    simpleFactory.getFamily2().then(function(data){
        $scope.family = data;
    }); 

This ensures the controller calling the factory method will get the data when it's ready. You can also handle error checking, etc, inside the factory and not in the controller, completely separating concerns.

Upvotes: 2

Related Questions