0

I am using the Axios library for my ajax requests so I created an instance of axios.

When I hit the endpoint /user/login, the success response will return me a token that I will use in the header for future calls as the API is secured.

The problem is when I do a console.log(authUser) the object is empty even though in the .then(), I am setting authUser.bearerToken.

Why is this happening? And what's the solution? Thanks. See code below.

var ax = axios.create({
    baseURL: 'http://api.site.test',
    timeout: 5000,
    headers: { 
        'X-Api-Client-Secret': 'xxxxxxxxxxxxxxxx' 
    }
});


var authUser = {};

// log the user in
ax.post('/user/login', {
    email: 'e@maiiiiiiiiil.com',
    password: 'ThisIsACoolPassword123!'
})
.then(function (response) {
    // set the bearer token
    authUser.bearerToken = response.data.token;
    ax.defaults.headers.common['Authorization'] = authUser.bearerToken;
})
.catch(function (error) {
    console.log(error);
});

console.log(authUser);
Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
Kenny
  • 675
  • 1
  • 7
  • 20
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – zero298 Aug 20 '18 at 20:45

2 Answers2

0

It's because its async. The code that talks to /user/login takes some time but your code continues.

So the order is

  1. Create base axios
  2. Define authUser as empty object
  3. Send a request to /user/login
  4. Console.log authUser
  5. Get the response from the post request

You can see it more clearly if you put 3 console logs.

var ax = axios.create({
    baseURL: 'http://api.site.test',
    timeout: 5000,
    headers: { 
        'X-Api-Client-Secret': 'xxxxxxxxxxxxxxxx' 
    }
});


var authUser = {};
console.log('authUser is ' + authUser);

// log the user in
ax.post('/user/login', {
    email: 'e@maiiiiiiiiil.com',
    password: 'ThisIsACoolPassword123!'
})
.then(function (response) {
    // set the bearer token
    authUser.bearerToken = response.data.token;
    ax.defaults.headers.common['Authorization'] = authUser.bearerToken;
    console.log('2. authUser is ' + authUser);
})
.catch(function (error) {
    console.log(error);
});

console.log('3. authUser is ' + authUser);

You will see it in the following order: 1, 3, 2 and not 1, 2, 3.

Bergur
  • 3,962
  • 12
  • 20
0

ax.post is asynchronous ( non blocking ) so it won't execute in the order you want it to execute i.e it can execute any time ( or concurrently ). you either have to use callbacks or async...await to handle this

function f() {

    var ax = axios.create({
        baseURL: 'http://api.site.test',
        timeout: 5000,
        headers: { 
            'X-Api-Client-Secret': 'xxxxxxxxxxxxxxxx' 
        }
    });

    var authUser = {};
    var response;

    ; ( async () => {

        // log the user in
        try {
            response = await ax.post('/user/login', {
                email: 'e@maiiiiiiiiil.com',
                password: 'ThisIsACoolPassword123!'
            })
        } catch(ex) {
           response = ex;
        } finally {
           if ( Error[Symbol.hasInstance](response) )
               return console.log(response);
           authUser.bearerToken = response.data.token;
           ax.defaults.headers.common['Authorization'] = authUser.bearerToken;
         }
    })(); 
    console.log(authUser)
}
0.sh
  • 2,659
  • 16
  • 37