christian.stock
christian.stock

Reputation: 201

Fetch data from AngularJS controller

I'm migrating jquery code to AngularJs.

My existing code grabs a list of names from an ajax call, which are then exposed via a get function which returns a list. This list sits in an object called "dataBrowser".

So basically in my existing code I can do:

$.each(this.dataBrowser.getList(), function(key, item)
{
    // print table row to html
});

Now I want to display that list in a table using ng-repeat.

My question is, how do I best access dataBrowser.getList() from the controller?

I have a global "application", so I could just grab it via application.dataBrowser.getList(), but I don't like using a global. Should I pass dataBrowser as an object into the controller when I create it?

What's the best approach?

Upvotes: 2

Views: 6579

Answers (2)

shaunhusain
shaunhusain

Reputation: 19748

Yeah so you should store the data in a service or factory typically that also deals with fetching the data and then inject that into a controller for use in the ng-repeat. I'll put together a basic sample plnkr here.

http://plnkr.co/edit/4NYFJ03ldsISSNF3aqoB?p=preview

angular.module('plunker', [])
  .factory('MyDataService', function($http){
    //Using $http here to do the AJAX request

    var service = {};

    service.getData = function(){
      return $http.get('data.json').then(function(resp){
        service.data = resp.data;
      })
    }

    service.getData();

    return service;
  })
  .controller('MainCtrl', function(MyDataService) {
    this.MyDataService = MyDataService;
  });

and the HTML

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="[email protected]" data-semver="1.4.0-rc.0" src="https://code.angularjs.org/1.4.0-rc.0/angular.js"></script>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl as mainCtrl">
    <p ng-repeat="thing in mainCtrl.MyDataService.data">Hello {{thing.label}}!</p>
  </body>

</html>

Upvotes: 3

tandrewnichols
tandrewnichols

Reputation: 3466

The best approach would be to put that ajax call in a service that uses $http and access the data from the service. So something like

var app = angular.module('app');
app.factory('DataBrowser' /*or whatever*/, function($http) {
  var data = {};
  // Or put this in a method on the returned object
  // if you want to invoke at some point other than load
  $http.get('/some/url').then(function(response) {
    data = response;
  });
  return {
    getData: function() {
      return data;
    }
  };
});

app.controller('SomeController', function($scope, DataBrowser) {
  $scope.data = DataBrowser.getData();
});

However, if the ajax call is complicated enough that you don't want to migrate it at this point, you could simply let the service access it from the global scope rather than make the call itself. Or have the current ajax call it throw on $rootScope with something like

$('body').scope().dataBrowser = data;

and then inject $rootScope. I guess the moral of the story is that there are a lot of ways to solve your problem, but in general, it's better not to mix angular with non-angular, not because I think you should care about what angular purists will say (I don't), but because angular is fairly opinionated. Most things just work better when kept within the angular ecosystem.

Upvotes: 4

Related Questions