Redis client.get not working but client.set is working - javascript

async function getRepos(req, res, next) {
try {
console.log('Fetching Data...');
const { username } = req.params;
const response = await fetch(`https://api.github.com/users/${username}`);
const data = await response.json();
const repos = data.public_repos;
// Set data to Redis
await client.setex(username, 3600, repos);
res.send(setResponse(username, repos));
} catch (err) {
console.error(err);
res.status(500);
}
}
// Cache middleware
async function cache(req, res, next) {
const { username } = req.params;
console.log(username)
await client.get(username, (err, data) => {
if (err) throw err;
if (data !== null) {
res.send(setResponse(username, data));
} else {
next();
}
});
}
When this code executes the set function works(checked by using redis-cli).But the get function does not work when I send the request to the api.

You're mixing the Redis client's promise API with the callback API. Don't set a callback if you want to use await and vice versa.
// Cache middleware
async function cache(req, res, next) {
const {username} = req.params;
console.log(username);
const data = await client.get(username);
if (data !== null) {
res.send(setResponse(username, data));
} else {
next();
}
}

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);
});

SINON - an issue mocking a middleware

I have the following middleware in a Node.js REST API
const Authorized = (req, res, next) => {
if (!req.headers["authorization"]) {
res.status(401).send("Unauthorized");
} else {
jwt.verify(req.headers["authorization"], PRIVATE_KEY, (err, decoded) => {
if (err) {
res.status(403).send("Forbidden");
} else {
req.businessId = decoded.businessId;
req.roleId = decoded.roleId;
next();
}
});
}
};
As you can see I'm adding to variables to the request object
In the mockup of my tests I'm trying to do this:
sandbox = sinon.createSandbox();
sandbox.stub(Authorized, "Authorized")
.callsFake(async (req, res, next) => {
req.businessId = businessAux.id;
return next();
});
But this doesn't work and my actual function to be tested needs this variable:
listPermissionAndRolesByPk() {
this.app.get(`${config.API_PATH}/permissionrolebypk`, Authorized.Authorized, async (req, res) => {
const id = req.query.id;
const businessId = req.businessId;
if (!id) return res.status(400).send(messages[23].message.replace("${object}", "Permission Id"));
try {
const permission = await PermissionDAO.getPermissionAndRolesByPk(id, businessId ? businessId : 0);
if (permission) {
return res.status(200).json(permission);
} else {
return res.status(404).send(messages[8].message.replace("${object}", "Permission"));
}
} catch (error) {
return res.status(error.httpCode).send(error.message);
}
});
}
Any help will be appreciated.

hash field with promiss function in nodejs from utilite

i have a class for hash data in nodejs .
this is my class :
const bycrypt = require("bcrypt");
module.exports = new (class Utilitie {
HashField(field) {
return new Promise((resolve, reject) => {
bycrypt.hash(field, bycrypt.genSaltSync(15), (error, hash) => {
if (error) return reject(error);
resolve(hash);
});
});
}
})();
and this is my controller for use this class for hash data :
async ResetPassword(req, res, next) {
const result = await this.ValidationAction(req, res);
if (result[0]) {
let user = await User.findOne({ userName: req.body.userName }).then(
(user) => {
if (!user) return this.Notfound(res);
user.password = Utilite.HashField(req.body.password).then(
(error, hash) => {
console.log("in controller", hash);
}
);
user.save();
}
);
this.Ok(res);
}
return this.BadRerquest(res, result[1]);
}
but it not hash field and it return the undefined .
whats the problem ? how can i solve this problem ????
The argument that your then callback receives will be the hash value. The return value of the then() call will be another promise. You meant to use await:
async ResetPassword(req, res, next) {
const result = await this.ValidationAction(req, res);
if (result[0]) {
const user = await User.findOne({ userName: req.body.userName });
if (!user) return this.Notfound(res);
user.password = await Utilite.HashField(req.body.password);
// ^^^^^
await user.save();
this.Ok(res);
} else {
this.BadRerquest(res, result[1]);
}
}

Getting result from MySQL

My backend is consist of Api and DB. When I want to get response from DB I have had delayed output by 1 query.
API (I think api is ok. Start read DB first)
app.post('/api/query', (req, res) => {
console.log(`\n Query input : ${JSON.stringify(req.body)}`);
let queryInput = (Object.values(req.body).join(' '));
if(!dbApi.checkArray(queryInput)){ //If array is not made from clear strings
res.json(dbApi.queryFromUser(queryInput));
}
else{
res.json(dbApi.queryOutput);
}
});
app.listen(dbConfig.server.port, () =>
console.log(`Server running on port ${dbConfig.server.port}`));
DB
queryOutput = [];
const receivingQuery =(queryInput) => {
db.query(queryInput, (err, result) =>{
if(err) throw err+' : '+queryInput;
queryOutput = result;
console.log("\nQuery output "+ JSON.stringify(queryOutput)); //Output (result) is ok
});
return queryOutput //Here is Output from previous query (sends to API)
}
module.exports = {
queryOutput: queryOutput,
queryFromUser: receivingQuery,
}
I tryied callback method and I rewrite it couple of times. But I dont have enough skill to solve it.
If You want to return result of query so simply do following things:
add query method to db module:
function query(sql, args = []) {
return new Promise(function(resolve, reject) {
db.query(sql, args, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
}
// extra feature, getting user by id
async function getUserById(id) {
const result = await query('SELECT * FROM users WHER id = ? LIMIT 1', [id]);
if (Array.isArray(result) && result[0]) return result[0];
return null;
}
module.exports = {
query,
getUserById, // export user by id
queryOutput,
queryFromUser: receivingQuery,
}
use it (with async and await):
app.post('/api/query', async (req, res) => {
try {
console.log('Query input:', req.body);
const queryInput = Object.values(req.body).join(' ');
const result = await dbApi.query(queryInput);
res.json(result);
}
catch (error) {
console.error(error);
res.status(500).json({message: 'Please try again soon'});
}
});
app.get('/api/users/:id', async (req, res) => {
try {
const user = await dbApi.getUserById(req.params.id);
if (!user) return res.status(404).json({message: 'User not found'});
res.status(200).json(user);
}
catch (error) {
console.error(error);
res.status(500).json({message: 'Please try again soon'});
}
});
app.listen(dbConfig.server.port, () =>
console.log('Server running on port', dbConfig.server.port));

Passing a variable from ReactJS frontend to NodeJS back end using a GET route

I am working on a react app and am trying to find a way to pass a variable I define in my front-end (Question.js) to my back-end (server.js) so that I can issue different queries. I have the code
//Question.js
state = {
data: null
};
componentDidMount() {
this.callBackendAPI()
.then(res => this.setState({ data: res.express }))
.catch(err => console.log(err));
}
callBackendAPI = async () => {
const response = await fetch('/express_backend');
const body = await response.json();
if (response.status !== 200) {
throw Error(body.message)
}
return body;
};
//server.js
con.connect(function (err) {
if (err) throw err;
con.query("SELECT question FROM s1questions WHERE ID = 1", function (err, result, fields) {
if (err) throw err;
app.get('/express_backend', (req, res) => {
var x = JSON.stringify(result[0].question);
res.send({ express: `${x}` });
});
});
});
Your sever should probably split your database connection from your route handler definitions. Also, you could use query parameters to access questions based on their id in the database.
// question.js
callBackendAPI = async () => {
const response = await fetch(`/express_backend?questionId=1`);
const body = await response.json();
if (response.status !== 200) {
throw Error(body.message)
}
return body;
};
// server.js
app.get('/express_backend', (req, res) => {
const { questionId } = req.query;
// query database for question by id
});

Categories

Resources