2

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?

1
  • You can assign this to a scope variable by calling an angularjs service. You can create service and write code there to fetch data. Commented Apr 16, 2015 at 1:38

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Got the service concept, that's exactly what I was looking for.
Question: and then inject $rootScope... Would you mind clarifying that? I'm migrating a big project (one year of work), so can only do it bit by bit, I want to avoid adding globals to the service, so doing global stuff in the old code is the better solution (as that will get migrated eventually).
You can inject $rootScope just like any other service. Something like app.controller('MyController', function($scope, $rootScope) { // . . . }); although $rootScope is not really much better than window. It's still, essentially a global scope: global to your angular application. But there are cases when it's useful.
just in case someone else wants to know how to access the service from legacy code: var service = angular.element(document).injector().get('LayerService');
3

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>

1 Comment

Thanks for the answer, that's great. I can't upvote as I don't have enough reputation yet :(

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.