简体   繁体   中英

Angular - Wait $http finish until go to the next line

It's a simple webshop. So I'd like to load several things before show the home page and the controller.

I decided that the index.html will be also the Master Page containing a header, the ui-view for routing templates , a sidebar containing the categories and a footer.

<body ng-app="app">
    <header ng-include="'./templates/masterPage/header.html'"></header>
    <div ui-view></div>
    <sidebar ng-include="'./templates/masterPage/sideBar.html'"></sidebar>
    <footer ng-include="'./templates/masterPage/footer.html'"></footer>
</body>

The things on header, sidebar and footer will came from a json file containgin everything I need such as categories, currency, name of the webshop and others things that's will never changes after load.

So, I created the following app.js...

angular
.module('app', [
    'ui.router'
])
.config(['$urlRouterProvider', '$stateProvider',
    function ($urlRouterProvider, $stateProvider) {
        $urlRouterProvider.otherwise('/');
        $stateProvider
            .state('home', {
                url: '/',
                templateUrl: 'templates/common/home.html',
                controller: 'homeCtrl',
            })
}])
.run(function ($rootScope, $http) {
    $rootScope.api = "http://127.0.0.1:5000/demoShop";
    var call = $rootScope.api + "/frontEnd/loadStructure";
    $rootScope.webshop = $http.get(call).then(function (response) {
        console.log('1');
        return response.data;
    });
    console.log("2");
})

The problem is: check the console.logs in the end....2 executes before 1 because I can't make the $http to wait until go to the next line. How can I do it ?

I need to populate the webshop variable on rootscope before do anything.

Simple answer: You can't.

Longer answer: You can wait for the AJAX request to finish. That's what you're already doing - it's the function in .then . You can put your code there. Question is - why do you need it to be finished first? Or maybe better question is why do you need to do the request in the controller? Isn't it a bit too late for that? See related answer from Misko Hevery .

I would suggest resolving the data when the homeCtrl for the root-route loads. Then you can access you webshop data apon instaciation of the controller. Consider the example below:

angular
.module('app', [
    'ui.router'
])
.config(['$urlRouterProvider', '$stateProvider',
    function ($urlRouterProvider, $stateProvider) {
      var resolveLoadStructure = function() {
        $rootScope.api = "http://127.0.0.1:5000/demoShop";
        var call = $rootScope.api + "/frontEnd/loadStructure";
        return $http.get(call);
      };

      $urlRouterProvider.otherwise('/');
      $stateProvider
      .state('home', {
        url: '/',
        templateUrl: 'templates/common/home.html',
        controller: 'homeCtrl',
        resolve: {
          loadStructure: resolveLoadStructure
        }
      });
}])
.controller('homeCtrl', function($scope, loadStructure) {
  $scope.webshop = loadStructure;
})

I found the problem. My mistaken is to set the $rootScope directly - Instead I set this inner the callback. I just made a small surgery and everything works fine. Take a look

.run(function ($rootScope, $http) {
    $rootScope.nodeshop = "http://127.0.0.1:5000/rawDemo";
    var call = $rootScope.nodeshop + "/frontEnd/loadStructure";
    var head = {}; 
    $http.get(call).then(function (response) {
        $rootScope.webshop = response.data; //See ? this variable is no longer set as result of the $http return !
        return response.data;
    });
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM