3

I'm working on AngularJs project which have top navigation items load from server using a service call

App.service('Menu', function($http){
   return {
       get:function(callback){
           $http.get('api/menu.json').success(function(menuData){
               callback(menuData);
           });
       }
   }
});

I'm using the same in my BaseController as mentioned below

App.controller('BaseCtrl', function($scope, Menu){
    $scope.menuData = {};
    Menu.get(function(menuData){
        $scope.menuData = menuData;
    });
});

My Menu looks blank for a while until the service call succeed and assign the value to the $scope.menuData is there any way to fetch the same before rendering the view.

Please let me know, I might have tried all possible ways to do this, but nothing worked :(

PS: I'm using AngularJS v1.2.9

4
  • 1
    have a look at ng-cloak Commented Apr 21, 2014 at 15:12
  • @MohammadSepahvand I have gone through the documentation of ng-cloak but didn't understand how it works and what part of my view I have to apply the same, can you please explain a bit. Thanks Commented Apr 21, 2014 at 15:18
  • ng-cloak basically doesn't display the binding expression in the view until the bindings have actually been set, I thought that was your problem initially, it's in a way a better approach than preventing the controller/view being rendered, because in a way the latter kills the point of SPAs having almost immediate route transitions and a very fluid nature. Commented Apr 21, 2014 at 15:26
  • I made a small edit to my answer, in the Menu service getMenuPromise should be pointing directly to the promise in the service, it shouldn't be a function returning a promise. Commented Apr 21, 2014 at 16:17

2 Answers 2

4

Return a promise from your service, and use that in your controller's resolve:

app.service('Menu', function($http) {
    var menuData = null;

    var promise = $http.get('api/menu.json').success(function (data) {
      menuData = data;
    });

  return{
          getMenuPromise: promise,
          getMenuData:function(){
            return menuData;
          }
   };
});

and in your route definitions:

$routeProvider
    .when('/home',{controller:'BaseCtrl',
    templateUrl:'../homeTpl.html',
    resolve:{
      'menuData':function(Menu){
        return Menu.getMenuPromise;
     }
    }})

Now when BaseCtrl is instantiated the data is there:

app.controller('BaseCtrl', function($scope,Menu) {
  $scope.menuData = MyService.getMenuData();
});
Sign up to request clarification or add additional context in comments.

1 Comment

The problem is my BaseCtrl is not assigned to any specific view, its a common controller for all views. Please suggest a way to resolve data in controller not in router. Thanks
3

The best way to make sure data is available before rendering a view is to use the resolve property on your route.

If it returns a promise it will resolve that promise before actually rendering your view.

.when('/blah', {
   templateUrl: '/path/to/view.html',
   controller: 'myController',
   resolve: {
      menuItems: function($http){
         return $http.get('api/menu.json');
      }
   }
});

That value will be passed in to your controller as a dependency:

angular.controller('myController', function(menuItems){
   $scope.menuData = menuItems;
});

2 Comments

The problem is my BaseCtrl is not assigned to any specific view, its a common controller for all views. Please suggest a way to resolve data in controller not in router. Thanks
@AshokVishwakarma - You can't accomplish what you want that way. You can create a promise to resolve things inside your control and call init() or something like that, but you can't prevent the view from loading without using the route. The best you could do inside your controller is to create some sort of ready flag that gets flipped when everything is loaded and simply ng-hide or ng-show your content when it is ready.

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.