0

I've written a service Auth with a function is_authenticated() that returns $http.get('/api/users/is_authenticated')

When I visit the API endpoint in the browser, I see the proper JSON.

{"authenticated":true} when the user is authenticated, and false when the user is not.

However, my console.log() below returns false 100% of the time (and it also logs it twice, not just once).

What's the problem here?

var is_authenticated = false;

Auth.is_authenticated()
    .success(function(data) {
        is_authenticated = data.authenticated;
    });

console.log(is_authenticated);

Service:

.factory('Auth', function($http) {
    return {
        is_authenticated: function() {
            return $http.get('/api/users/is_authenticated');
        },
Billy Assim
  • 227
  • 2
  • 4
  • 15

2 Answers2

2

console.log() takes a reference to the object specified and immediately runs a (typically background) process to write it to the log. What it writes depends entirely on timing. You run into this a LOT with async calls - if you step through it with a debugger or set a breakpoint, it prints the correct value. If you run it raw, it fails. It's because it's executing before your network request has completed.

Move the console.log inside the success function:

Auth.is_authenticated().success(function(data) {
    is_authenticated = data.authenticated;
    console.log(is_authenticated);
});

You should also trap possible failures to this call as well. If you get any kind of error (like a CORS violation, which Chrome now enables by default) you'll never hit this code block and you'll still be scratching your head:

.error(function(data, status, headers, config) {
    console.log('Fail!');
});

Finally, note that although Factories are useful patterns, unless you're specifically making use of how they behave, you can usually save a line or two of code by making them a service instead. You don't need to return an object - you just set your properties and methods on 'this'.

This can be important as you build bigger services like authentication providers where you really want those to be singletons...

Chad Robinson
  • 4,575
  • 22
  • 27
0

One way is to use $timeout while accessing the data outside the success function. Just set a reasonable delay.
Another way is to use $broadcast inside the success() to signal the completion of the ajax call before you access the data, if you are accessing data elsewhere.

Jaydee88
  • 66
  • 1
  • 7