QoP QoP - 5 months ago 18
AngularJS Question

AngularJS - Wait to Load data to display the view

I am really new to AngularJS and after reading several questions and some articles I am a little confused about the correct way to load data and wait till its loaded to display the view.

My controller looks like this

app.controller('ResultsController', ['$scope','$http', '$routeParams', function($scope, $http, $routeParams) {
$scope.poll = {};
$scope.$on('$routeChangeSuccess', function() {
showLoader();
$http.get("rest/visualizacion/" + $routeParams.id)
.success(function(data) {
$scope.poll = data;
hideLoader();
})
.error(function(data) {
// Handle error
});
});
}]);


I have seen there are people who create a service for $http calls, is it necessary? Why is it better?

Answer

The appropriate way to do that is to use the resolve property of the route. From the documentation:

resolve - {Object.<string, function>=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired. The map object is:

  • key – {string}: a name of a dependency to be injected into the controller.
  • factory - {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before its value is injected into the controller. Be aware that ngRoute.$routeParams will still refer to the previous route within these resolve functions. Use $route.current.params to access the new route parameters, instead.

So, if you want poneys to be retrieved from the backend before the router goes to the poney list page, you would have

resolve: {
    poneys: function($http) {
        return $http.get('/api/poneys').then(function(response) {
            return response.data;
        )};
    }
}

And your controller would be defined as

app.controller('PoneyListCtrl", function($scope, poneys) {
    $scope.poneys = poneys;
    // ...
});

Of course, you could also put the code making the $http call and returning a list of poneys in a service, and use that service in the resolve.

Comments