I'm trying to write a function in nodejs that reads the information about users from a json file (I know it's not secure, just an exercise), logs whether the details are correct and sends a response. I wrote this async function:
async function getUser(sUsername) {
fs.readFile('db/users.json', (err, data) => {
if (err) {
console.log(`An error has occured in getUser function`)
}
let users = JSON.parse(data)
userNamesFromFile = Object.keys(users);
console.log(`Data is: ${data}`)
console.log(`Users after parsing are: ${userNamesFromFile}\n`)
for (currUser in userNamesFromFile) {
`Currently checking comparing to user: ${currUser}\n`
if (currUser === sUsername) {
var oUser = new User(currUser, users[currUser].password);
return oUser;
}
}
})
}
And I call it here :
getUser(oBody.username.toLowerCase()).then(oFoundUser => {
console.log(`Finished the async function, found user ${oFoundUser}`)
if (oFoundUser) {
if (oBody.password.toString() === oFoundUser.password.toString()) {
console.log("Login successful")
res.statusCode = 200
req.session.username = oFoundUser.username;
}
else {
console.log("Wrong password")
res.statusCode = 401;
}
}
else {
res.statusCode = 401
console.log("No user with such a name exists")
}
res.send();
})
This is the log I get from the server when inputting the correct details of a user:
Finished the async function, found user undefined
No user with such a name exists
POST /login 401 7.822 ms - -
Data is: {
"testuser1": {
"password": 12345
},
"testuser2": {
"password": 6789
}
}
Users after parsing are: testuser1, testuser2
It looks like he's saying that the async function runs and only then logs the information I'm logging from the async function. It doesn't even get into the loops comparing the users to what I just got from my json file. I put what I want to do with the return value of the async function in a .then. Shouldn't it run in the order I expect it to?
Thanks,
Ben
I found a solution. I guess using a callback is the right answer. If I understand correctly, the async function doesn't return the promise that resolves as the "return" value I gave it, but I can call a comeback inside the resolving in the async function. Is this correct?
async function getUser(sUsername, callback) {
return fs.readFile('db/users.json', (err, data) => {
if (err) {
console.log(`An error has occured in getUser function`)
}
let users = JSON.parse(data)
userNamesFromFile = Array.from(Object.keys(users));
for (let i = 0; i < userNamesFromFile.length; i++) {
currUser = userNamesFromFile[i]
if (currUser === sUsername) {
var oUser = new User(currUser, users[currUser].password);
console.log(`Returnign callback with ${oUser.toString()}` )
return callback(oUser);
}
if (i === userNamesFromFile.length - 1) {
return callback(false)
}
}
})
}
getUser(oBody.username.toLowerCase(), oFoundUser => {
console.log(`Finished the async function, found user ${oFoundUser}`)
if (oFoundUser) {
if (oBody.password.toString() === oFoundUser.password.toString()) {
console.log("Login successful")
res.statusCode = 200
req.session.username = oFoundUser.username;
}
else {
console.log("Wrong password")
res.statusCode = 401;
}
}
else {
res.statusCode = 401
console.log("No user with such a name exists")
}
res.send();
})
Thanks,
Ben