0

I really new with AngularJs and I'm trying to create multiple routes with different $http requests. My problem start when the route change and the page content show later. I figure it out in some way and i think its not the right way. Hope someone can tell me if there is a better way.

Note: AngularJs version: 1.6 | Using ui router

main.js

var asTwl = angular.module('asTwl', ['ui.router']);

asTwl.controller('generals', function($scope, $http, $timeout){

    $scope.pageLoader = false;

    $scope.getPageData = function(path, postData, obj){
        $scope.pageLoader = true; 
        $http({
            method: 'post',
            url: path,
            data: postData,
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        })
        .then(function(response) {
            if (response.data) {
                $scope.data[obj] = JSON.parse(response.data);
                $timeout(function(){
                    $scope.pageLoader = false;
                }, 100)
             }
        })
        .catch(function(e) {
            new Error('Error: ', e);
            throw e;
        })
    }
});

asTwl.controller('homePage', function($scope, $http){   
    var postData = {
      //data...
    }
    $scope.getPageData('path', postData, 'home')
})

asTwl.controller('singlePage', function($scope, $http, $stateParams){   
    var postData = $stateParams;
    $scope.getPageData('path', postData, 'page')
})

asTwl.controller('categoryPage', function($scope, $http, $stateParams){   
    var postData = $stateParams;
    $scope.getPageData('path', postData, 'category')
})

asTwl.config(function($stateProvider, $urlRouterProvider, $locationProvider){

    $urlRouterProvider.otherwise('/');

    $stateProvider
    .state('home', {
        url: '/',
        templateUrl : 'templates/pages/home.html',
        controller : 'homePage'
    })
    .state('info', {
        url: '/info/:id',
        templateUrl : 'templates/pages/info.html',
        controller : 'singlePage'
    })
    .state('category', {
        url: '/category/:type/:id',
        templateUrl : 'templates/pages/category.html',
        controller : 'categoryPage'
    })
});

Thank you!

1
  • Angular version? Also this looks like UI router. if so please specify it in the question Commented Jan 26, 2017 at 6:57

3 Answers 3

4

First, wrap your $http calls to services. Next,try to use resolve https://github.com/angular-ui/ui-router/wiki#resolve

Edit

Ok, example is here (without wrapping to service):

$stateProvider
.state('home', {
    url: '/',
    templateUrl : 'templates/pages/home.html',
    controller : 'homePage',
    resolve: {
       routeData:  function($http){
        return $http({
        method: 'post',
        url: 'path',
        data: postData /* your POST data - i don't know what is it for your code*/,
        headers: { 'Content-Type': 'application/x-www-form-urlencoded'               }
        })
     }
    }
})
.state('info', {
    url: '/info/:id',
    templateUrl : 'templates/pages/info.html',
    controller : 'singlePage'
})
.state('category', {
    url: '/category/:type/:id',
    templateUrl : 'templates/pages/category.html',
    controller : 'categoryPage'
})

And in controller:

asTwl.controller('homePage', function($scope, routeData){   
      $scope.someData = routeData;
})
Sign up to request clarification or add additional context in comments.

4 Comments

You can show me a specific example? something with my code?...i tried use resolve but its became very difficult when i added more route states.
I upvoied this because this is the correct way to go, you can and should abstract http call to an angular service/services and then resolve function would be simpler, also you can have many "state router" files. so no need for one big file. the plus for moving must have http promises to state resolving is that the actual page change happens only when the client got all the data needed
Thank you! but if i need it for every state (i have something like 15 different state that look similar)?
You will need to add "resolve" for every state, but you can use universal service for requests, see @Pankaj Parkar answer.
1

You should first create a service which will be responsible for communicating with Server/API for playing around with data. You could include that method getPageData in that, it returns a promise object.

Service

app.service('myService', function($http){
   var self = this;
   self.getPageData = function(path, postData){
        return $http.post(path,postData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' });
        .catch(function(e) {
            new Error('Error: ', e);
            throw e;
    });
});

Then you could easily utilize the resolve option of state of ui-router will wait till your ajax promise gets resolved.

.state('info', {
    url: '/info/:id',
    templateUrl : 'templates/pages/info.html',
    controller : 'singlePage',
    resolve: {
       getData: function(myService) {
          return myService.getPageData('path', {}, 'info')
       }
    }
})

1 Comment

OP using $stateParameters, which can be passed to resolve function via angular DI
0

In a nutshell your routes have to be changed like this:

.state('category', {
    resolve: {
       data : ($stateParams, dataService) => dataService.getData('path', $stateParams, 'category')
    },
    url: '/category/:type/:id',
    templateUrl : 'templates/pages/category.html',
    controller : 'categoryPage'
})

And getData method should be refactored to the service (dataService)

Comments

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.