How to execute async function - javascript

I'm a React and Socket.io newbie. My async function below is not executing. My socket emit is working correctly because "message received" is being console logged. However, nothing else is.
socket.on('connected', function(data) {
//load all messages
console.log('message received');
(async () => {
try {
console.log('searching for Schema');
const conversation = await Conversation.find({roomId: data.roomid}).populate('messages').lean().exec();
const mess = conversation.map();
console.log('Schema found');
}
catch (error) {
console.log('Schema being created');
Conversation.create({type: data.roomid});
}
});
});

Just execute your function, adding "()" at the end:
socket.on('connected', function(data) {
//load all messages
console.log('message received');
(async () => {
try {
console.log('searching for Schema');
const conversation = await Conversation.find({roomId: data.roomid}).populate('messages').lean().exec();
const mess = conversation.map();
console.log('Schema found');
}
catch (error) {
console.log('Schema being created');
Conversation.create({type: data.roomid});
}
})(); // <- just this
});
I recommend to you create a function separately, will looks better and clear.

You are not actually calling the async method, just defining it and moving on.
Try this:
const searchForSchema = async (data) => {
try {
console.log('searching for Schema');
const conversation = await Conversation.find({roomId: data.roomid}).populate('messages').lean().exec();
const mess = conversation.map();
console.log('Schema found');
}
catch (error) {
console.log('Schema being created');
Conversation.create({type: data.roomid});
}
}
socket.on('connected', (data) => {
//load all messages
console.log('message received');
await searchForSchema(data);
});

Related

Redis get function

I'm getting github repo data, and then i store it in redis with set. with get am getting current data, but when i trying add function to get it's not working.
let redisClient;
(async () => {
redisClient = redis.createClient();
redisClient.on("error", (error) => console.error(`Error : ${error}`));
redisClient.on("connect", function () {
console.log("Redis Connected!");
});
await redisClient.connect();
})();
// Make request to Github for data
async function getRepos(req, res, next) {
try {
console.log("Fetching Data...");
const { username } = req.params;
// with this am getting result
const cacheResults = await redisClient.get(username);
console.log(cacheResults);
// with this am not getting result, how can i fix this?
redisClient.get(username, (err, data) => {
console.log(data);
});
const response = await fetch(`https://api.github.com/users/${username}`);
const data = await response.json();
const repos = data.public_repos;
// Set data to Redis
redisClient.set(username, JSON.stringify(repos));
res.send(setResponse(username, repos));
} catch (e) {
console.log(e);
res.status(500);
}
}
it's don't console.log(data), i searched a lot and everyone have one example how to use get function, but in me case it's don't log, whats am doing wrong?
this is my cache function
// Cache middleware
async function cache(req, res, next) {
const { username } = req.params;
try {
await redisClient.get(username).then((data) => {
if (data !== null) {
res.send(setResponse(username, data));
} else {
next();
}
});
} catch (error) {
console.log(error.toString());
}
}
app.get("/repos/:username", cache, getRepos);
it's works, but time finish times with cache and without it are same? am doing something wrong?
can you try like this
redisClient.get(username).then((data) => {
console.log(data);
});

Facebook Graph request with async await

I want to make a call to my backend (registerSanctumFacebook method) after a facebook Graph request to get user profile info (email), however I'm getting the following error:
await is only allowed within async functions
Pretty self explanatory, the problem is, I don't know how to make graph start method to work with async-await...
const getInfoFromToken = async (token) => {
const PROFILE_REQUEST_PARAMS = {
fields: {
string: 'email',
},
};
const profileRequest = new GraphRequest(
'/me',
{token, parameters: PROFILE_REQUEST_PARAMS},
(error, user) => {
if (error) {
console.log('login info has error: ' + error);
} else {
//this.setState({userInfo: user});
console.log('user:', user);
}
},
);
new GraphRequestManager().addRequest(profileRequest).start();
let response = await registerSanctumFacebook(user.email,user.id);
};
How I call getTokenInfo method:
const loginWithFacebook = async () => {
LoginManager.logInWithPermissions(['email']).then(
login => {
if (login.isCancelled) {
console.log('Login cancelled');
} else {
AccessToken.getCurrentAccessToken().then(data => {
const accessToken = data.accessToken.toString();
console.log('accessToken',accessToken);
getInfoFromToken(accessToken);
});
}
},
error => {
console.log('Login fail with error: ' + error);
},
);
};
As per your problem statement, I think you should add await on this line
await new GraphRequestManager().addRequest(profileRequest).start();
await will only work if the function after await keyword is also async.
or declare registerSanctumFacebook as async

How do I get this function to run synchronously?

async await is very confusing. I have the below code and here I am trying to implement a create user function that first needs to check if the user exists in my MySQL database. I have the initial setting of the user where I call await on my findByUsername function. However, The function finishes after my if(!user) code has been executed.
I want the program to wait for the findByUsername function to finish and then perform the check on whether the user exists or not.
const { username, password, firstname, permission } = req.body;
let user = await User.findByName(req.body.username, (err, data) => {
if (err) {
if (err.kind === "not_found") {
console.log("finished");
return null;
} else {
console.error("error occurred");
}
} else {
console.log("finished too");
return data;
}
});
if (!user) {
console.log("couldnt find user");
res.status(404).send("couldnt find it :(");
} else {
console.log("found user");
res.send("found them");
}
===EDIT===
I am getting another that has also been confusing me where it says that result is not a function inside of my findByName function on my User model.
sql.query(`SELECT * from users WHERE username = '${username}'`, (err, res) => {
if (err) {
console.log("error ", err);
result(err, null);
return;
}
if (res.length) {
console.log("found user: ", res[0]);
result(null, res[0]);
return;
}
console.log("couldnt find");
return { kind: "not_found" }, null;
});
};
We must use await inside an async function.
For example:
const getUser = async (username) => await User.findByName(username);
Then call that function inside a try catch
try {
user = getUser(someUsername)
} catch (error) {
// Handle errors here
}
// Code here will only run once getUser is finished
Since i don't know your UserService i don't know if "User.FindByName" is a async function. but if that is the case you could do it like this:
const { username, password, firstname, permission } = req.body;
try {
let user = await User.findByName(req.body.username);
if (!user) {
console.log("couldnt find user");
res.status(404).send("couldnt find it :(");
} else {
console.log("found user");
res.send("found them");
}
} catch (e) {
res.status(400).send(e);
}
Are you able to change the definition of User.findByName?
Instead of using await and also passing in a callback, why not remove the callback and process it synchronously?
let user = await User.findByName(username);
// Handle response here
this will solve your Problem If you are using sequelize with mysql you can use where
condition in your code so you can use more conditions in it
const { username, password, firstname, permission } = req.body;
try {
let user = await User.findOne({
where: { username: req.body.username },
attributes: { exclude: ['password', 'signup_token'] }
});
if (!user) {
console.log("couldnt find user");
res.status(401).send("couldnt find user with username" +
(req.body.username));
} else {
console.log("User Found");
return res.status(200).send("User Found With Username" +
(req.body.username));
}
} catch (error){
console.log(error);
return res.status(500).send(error);
}
The function finishes after my if(!user) code has been executed.
That is because you are mixing async/await with callbacks which you should not.
// Here you are mixing async/await and callbacks
let user = await User.findByName(req.body.username, (err, data) => { /*....*/ });
// it is the same as
function findByNameCallback(err, data) { /*.....*/ }
let user = await User.findByName(req.body.username, findByNameCallback);
// -- So you either remove the callback from the equation
var user;
try {
user = await User.findByName(req.body.username);
} catch (err) {
// Handle error
}
// Work with the user object...
// ----
// Or remove the async/await stuff
User.findByName(req.body.username, findByNameCallback);

How to work with Async/Await in expressjs router?

I've been battling with an issue concerning Async/Await, I'm relatively new to Nodejs. I have a repository where I connect directly to my mongodb collection to retrieve some data it but when I connect my controller to this repository, I get a nulled response.
Please checkout my code below:-
SyncRepository.js
const mongoose = require('mongoose');
exports.ItemRepo = async (limit) => {
try {
await mongoose.connection.db.collection('items_1087342')
.find({}, {timeout: false}).limit(limit).toArray((err, results) => {
// results.forEach(e => {
// console.log(e.item_id);
// }); //This works well
return results;
});
} catch (e) {
throw Error('Error Loading Data:- ' + e.message);
}
};
SyncController.js
const syncRepo = require('../../../Repositories/Sync/SyncRepository');
exports.getItem = async (req, res) => {
try {
await syncRepo.ItemRepo(7)
.then(element => {
console.log(element);
return res.json(element); //This return null
});
// return await res.json(await syncRepo.ItemRepo(7));
} catch (e) {
return res.status(400).json({ status: 400, message: e.message });
}
};
You are mixing async/await and traditional Promise syntax. Try this :
SyncRepository.js
const mongoose = require('mongoose');
exports.ItemRepo = limit => {
return mongoose.connection.db.collection('items_1087342')
.find({}, {timeout: false})
.limit(limit)
.exec() // see #Enslev's explanation in the comments
};
SyncController.js
const syncRepo = require('../../../Repositories/Sync/SyncRepository');
exports.getItem = async (req, res) => {
try {
let element = await syncRepo.ItemRepo(7)
return res.json(element);
} catch (e) {
return res.status(400).json({ status: 400, message: e.message });
}
};

return result from memcached.get()?

I am using npm memcached package https://www.npmjs.com/package/memcached
It is possible to return data from memcached get method?
Now return data is undefined/
memcached.set('foo', 'bar', 10, function (err) { });
let data1;
memcached.get('foo', function (err, data) {
console.log(data); // bar
data1 = data
});
console.log(data1); // undefined
let data2 = memcached.get('foo', function (err, data) {
console.log(data); // undefined
return data;
});
console.log(data2); // undefined
let data3 = async () => {
let result = await memcached.get('foo', function (err, data) {
console.log(data); // bar
});
console.log(result); // undefined
return result;
}
console.log(data); // {}
You can't return from get() as it's an asynchronous callback. What you can do is:
with callbacks:
memcached.get('foo',(err, data) => {
if(err) {
console.log('error: ', err);
} else {
console.log('data: ', data);
}
});
with promises:
memcached.get('foo')
.then((data) => {
console.log('data: ', data);
})
.catch((err) => {
console.log('error: ', err);
});
and with async/await:
const getData = async () => {
try {
const data = await memcached.get('foo');
console.log('data: ', data);
} catch (err) {
console.log('error: ', err);
}
}
hope this helps :)
Since memcached is async you can't really return from it, altho I see OP found a way via a promisify wrapper. What you can do is call another function from inside the callback.
Working with async socket communication I've had to split up a lot of my workflows into request and receives.
memcached.get('foo',(err, data) => {
doStuff(data);
});
function doStuff(data) {
//do some stuff here
}
Of course you could always do your work with the data inside the handler too. But in some cases that isnt the best approach.

Categories

Resources