I am having trouble with what I believe is asynchronous functions. I have some end points pointing towards a host with some requests to get a token from my login data, and another get request that uses that token to retrieve information about my profile.
The issue I believe I am having is that the login get request runs before my token is actually saved to my header variable. Is someone able to explain a way that I can wait for the token to be received before my api sends any other requests out?
const fastify = require('fastify')({ logger: true });
const axios = require('axios');
const fs = require('fs');
require('dotenv').config();
const username = process.env.USERNAME
const password = process.env.PASSWORD
let token
const instance = axios.create({
baseURL: process.env.URL,
headers : {
'Authorization': `Bearer ${token}`
}
})
async function login() {
const response = await instance.post('/login', {username, password})
token = response.data['token'];
console.log(token);
}
async function me() {
const response = await instance.get('/me')
console.log(response.data);
}
login().then(me())
Thanks!
2
Answers
@noassl was correct with their comment. The real issue I was running into was with my incorrect assignment of the token. The authorization token was initially assigned undefined but I am not sure why I was unable to change it. I am assuming this has something to do with the way Axios instances function. To correct this issue, I moved the assignment of the instance inside the login function.
This is because JavaScript’s asynchronous behavior allows login() to start, but not necessarily complete before me() is executed.
To fix this, you should ensure that me() only runs after the login() function has completed and the token is available. The correct way to handle this is to use await with login() inside an asynchronous function or to chain the .then() method.
Here’s how you can refactor your code to fix the issue:
Solution 1: Use async/await in an async function
Explanation:
login() is an asynchronous function that fetches the token from your login endpoint.
me() is another asynchronous function that relies on the token.
performRequests() is an async function that ensures login() completes before me() is called.
We use await in front of both login() and me() to ensure they run sequentially — me() won’t execute until login() is finished and the token is set.
Solution 2: Use .then() with promise chaining
If you prefer to use .then() instead of async/await, you can also chain the promises. Here’s how:
Explanation:
login() now returns a promise (which is returned by instance.post()), so you can chain .then() to run the me() function once login() resolves successfully.
This works because .then() ensures that me() will only run after login() finishes.
Either solution will fix the problem, but using async/await is generally more readable and cleaner, especially when dealing with multiple asynchronous operations.