1

I have a problem to initialize controller in AngularJS.

Below is the process which I want to implement.

  1. Get data from mongoDB by $http before DOM is ready.
  2. By Using the data, some div element should be created using ng-repeat.

But the problem is that the view is rendered before controller gets data from $http.

So I searched all over the stack-overflow and google, and found about ui-router's resolve function.

Below is my ui-router code.

            .state('floor', {
            url: '/floor/:domainId',
            templateUrl: 'modules/floor/views/floor.client.view.html',
            controller: 'FloorController',
            resolve: {
                initData: ['$http', '$stateParams', function($http, $stateParams) {
                    return $http.get('/users/getFloor/' + $stateParams.domainId).success(function(user) {
                        return $http.get('/users/' + user._id + '/data/get').success(function(data) {
                            return data;
                        });
                    });
                }]
            }
        })

The first $http is to get user id from domain id. (e.g. User can connect to /floor/my_personal_domain_address), and the second $http is what I need for initial data.

This is my Controller code.

angular.module('floor').controller('FloorController', ['$scope', 'initData',
    function($scope, initData) {
        console.log(initData);
}]);

Small tip or search keyword or anything will be very thankful for me. I'm still learning AngularJS so just give me a small tip please.. Thank you!

UPDATE

This was my misunderstanding of how controller works. As some people commented, I didn't have to use resolve to retrieve data before controller initialized. The problem was occurred because I declared array variable used in ng-repeat as [] for the first time and client shows error. If I declare the variable after I get value from database, controller data-bind it to view properly. So the problem is solved. Thank you all for valuable comments and answers.

UPDATE 2

Anyway, ui-router's resolve can return a value even though it is promise. I worked for it for some hours, and what I found out is that if I return $http promise in resolve, controller can get its data when successful. But if $http error is occurred in resolve, nothing can catch it. So if there's someone who wants to use resolve to send data to controller before it is initialized, I think it must be used with care.

jolacaleb
  • 69
  • 2
  • 7
  • I could be wrong but im pretty sure you should be able to do all of your http requests in your controller (should use a service before instantiated in your controller). – Joe Lloyd Aug 25 '15 at 10:43
  • Yes, you can either inject $http or (better) use a service. I don't understand why you need the data before the controller gets initialized. Is it a UX requirement? because if not, by the magic of databinding, you can fetch the data later and have it displayer in your ng-repeat –  Aug 25 '15 at 10:45
  • possible duplicate of [AngularJS - Running a function once on load](http://stackoverflow.com/questions/32158145/angularjs-running-a-function-once-on-load) – Medet Tleukabiluly Aug 25 '15 at 10:48
  • Thank you for reading my question. As Sphaso said, I have to search more to use service instead of resolve for router can't catch $http error. – jolacaleb Aug 25 '15 at 10:48
  • in "resolve" you need to return promise and angular will inject resolved value. – webduvet Aug 25 '15 at 13:07
  • On behalf of @Fantoni0: I am not sure if this would solve your problem, but give a look to [$timeout](https://docs.angularjs.org/api/ng/service/$timeout). – Mogsdad Aug 25 '15 at 13:25

2 Answers2

1

Get data from mongoDB by $http before DOM is ready.

In this case probably the simpler solution would be not to make any tricky $http requests before Angular initialization but instead just to embed your data as JavaScript global variable into the main HMTL page just before loading of angular.min.js script.

Vlad Rudenko
  • 2,363
  • 1
  • 24
  • 24
0

I don't know if I get your question correctly, but this should help you:

(from the ui-router docs https://github.com/angular-ui/ui-router/wiki)

// Another promise example. If you need to do some 
// processing of the result, use .then, and your 
// promise is chained in for free. This is another
// typical use case of resolve.
promiseObj2:  function($http){
   return $http({method: 'GET', url: '/someUrl'})
      .then (function (data) {
          return doSomeStuffFirst(data);
      });
},     

So you'd have to use .then() instead of .success() and it should work.

m.brand
  • 658
  • 5
  • 12