Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

AngularJS API calls syncronously?

I have a application root controller.

app.controller("RootController", ['$scope', '$route', '$routeParams', '$location', '$rootScope', 'User', function($scope, $route, $routeParams, $location, $rootScope, User)
  {
    self = this;
    $scope.user = User.get();

    // If undefined user then send to homepage 
    if($scope.user === false)
    {
      $location.path("/");
    }

    $scope.$on('$routeChangeStart', function (e, next, current)
    {
      // Get the current permissions scope
      userPerms = $scope.user.permissions;
      routeReqPerms = next.access.requiredPermssions;
      permissions = userPerms&routeReqPerms;

      if (next.access !== false && !next.access.allowAnonymous && !$scope.user.authenticated)
      {
        $location.path("/");
      }
      else if(!next.access.allowAthenticated && $scope.user.authenticated)
      {
        $location.path("/dashboard");
      }
      else if(!next.access.allowAnonymous && permissions == 0)
      {
        $location.path("/");
      }
    });

    $rootScope.$on("$locationChangeStart", function (event, next, current)
    {
      for (var i in window.routes)
      {
        if (next.indexOf(i) != -1)
        {
          if (!window.routes[i].access.allowAnonymous && !this.user.authenticated)
          {
            $location.path("/");
          }
        }
      }
    });

    self.returnHome = function()
    {
      $location.path('/');
    }
  }]);

The idea of the controller is that at the beginning of page load it tries to get the user from the User factory. Then whenever routes change it checks to see the status of the root controller user (ie authenticated or not) and based on those parameters it decides to throw it to the homepage where the login form is or to allow it to continue.

The problem I am having is with the Asyncronicity of Javascript or more the Asyncronicity of $http.

In my User factory get function looks like this...

var get = function() { if(!user.authenticated) { $http.get('/api/user/profile') .success(function(response) { user.authenticated = true; user.permissions = 1; console.log(user); }); return user; } else { return user; } }

The problem is it always returns the user before the http request finishes. I do not know how to prevent this. I could use some help. I tried to use promises, but that doesn't seem to help the situation on the initial load of the page.

2 Answers

When you post code make sure the ``` is on it's own line. Like this:

controller("RootController", ['$scope', '$route', '$routeParams', '$location', '$rootScope', 'User', function($scope, $route, $routeParams, $location, $rootScope, User) { self = this; $scope.user = User.get();

// If undefined user then send to homepage 
if($scope.user === false)
{
  $location.path("/");
}

$scope.$on('$routeChangeStart', function (e, next, current)
{
  // Get the current permissions scope
  userPerms = $scope.user.permissions;
  routeReqPerms = next.access.requiredPermssions;
  permissions = userPerms&routeReqPerms;

  if (next.access !== false && !next.access.allowAnonymous && !$scope.user.authenticated)
  {
    $location.path("/");
  }
  else if(!next.access.allowAthenticated && $scope.user.authenticated)
  {
    $location.path("/dashboard");
  }
  else if(!next.access.allowAnonymous && permissions == 0)
  {
    $location.path("/");
  }
});

$rootScope.$on("$locationChangeStart", function (event, next, current)
{
  for (var i in window.routes)
  {
    if (next.indexOf(i) != -1)
    {
      if (!window.routes[i].access.allowAnonymous && !this.user.authenticated)
      {
        $location.path("/");
      }
    }
  }
});

self.returnHome = function()
{
  $location.path('/');
}
}]);

As for your problem. I believe this is the solution: http://stackoverflow.com/questions/28450443/how-to-prioritize-requests-in-angular-http-service

I wish I was able to edit my post I would have fixed the ``` issue.

As for the issue at hand. I ended up assuming if the token was stored that the user was valid and gave them basic permissions, and then did my call to get profile which if it fails will reset the user and delete the token. Thanks for the response though.

You should see three little dots at the bottom of each post you make which gives you the ability to edit your posts.

wow that was totally un-obvious. Thanks.