Unable to GET value from redis - javascript

I am trying to get a value from redis which I have set. When I call the checkCache function I get "CACHE: null" and afterwards it logs "NO ERROR + the data". I dont understand why since I used await.
const redis = require("redis");
const client = redis.createClient({
port : procces.env.PORT,
host : procces.env.HOST,
password : procces.env.PASSWORD,
});
const checkCache = async (key) => {
await client.get(key, (err, data) => {
if(err) throw err;
console.log("NO ERROR + " + data);
if(data !== null) { return JSON.parse(data); }
});
return null;
};
I call the methode like this:
const findAll = async(user) => {
const cache = await checkCache(user);
console.log('CACHE: ' + cache); // returns null
};

Module redis doesn't support Promise.
For this you have promisify it
const Promise = require('bluebird');
const redis = Promise.promisifyAll(require("redis"));
EDIT:
const Promise = require('bluebird');
const redis = Promise.promisifyAll(require("redis"));
const client = redis.createClient({
port : process.env.PORT,
host : process.env.HOST,
password : process.env.PASSWORD,
});
const checkCache = async (key) => {
const data = await client.getAsync(key);
console.log("NO ERROR + " + data);
if(data !== null) { return JSON.parse(data); }
return null;
};

Related

NodeJS API Proxy Server - Post Requests Error 404 - Routing

I am new at NodeJS and am trying to implement a proxy server for my GET requests. GET requests works fine can also update my UI as it should be by performAction and chained promises, however something is wrong with my POST request, I always get a 404 despite I defined the route, it pops up after UI update. Can anybody help me? Thanks!
SERVER
const express = require('express')
const cors = require('cors')
const rateLimit = require('express-rate-limit')
require('dotenv').config()
const errorHandler = require('./middleware/error')
const bodyParser = require('body-parser')
// support parsing of application/json type post data
//support parsing of application/x-www-form-urlencoded post data
const PORT = process.env.PORT || 5000
const app = express()
app.use(bodyParser.urlencoded({ extended: true }));
// Rate limiting
const limiter = rateLimit({
windowMs: 10 * 60 * 1000, // 10 Mins
max: 100,
})
app.use(limiter)
app.set('trust proxy', 1)
// Enable cors
app.use(cors())
// Set static folder
app.use(express.static('public'))
// Routes
app.use('/api', require('./routes'))
// Error handler middleware
app.use(errorHandler)
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))
API PROXY SERVER
const url = require('url')
const express = require('express')
const router = express.Router()
const needle = require('needle')
const apicache = require('apicache')
// Env vars
const API_BASE_URL = process.env.API_BASE_URL
const API_KEY_NAME = process.env.API_KEY_NAME
const API_KEY_VALUE = process.env.API_KEY_VALUE
// Init cache
let cache = apicache.middleware
let projectData = {}
router.get('/', cache('2 minutes'), async (req, res, next) => {
try {
const params = new URLSearchParams({
[API_KEY_NAME]: API_KEY_VALUE,
...url.parse(req.url, true).query,
})
console.log('${API_BASE_URL}?${params}')
const apiRes = await needle('get', `${API_BASE_URL}?${params}`)
const data = apiRes.body
// Log the request to the public API
if (process.env.NODE_ENV !== 'production') {
console.log(`REQUEST: ${API_BASE_URL}?${params}`)
}
res.status(200).json(data)
} catch (error) {
next(error)
}
})
function sendForecastData(req, res) {
const { date, temp, content } = req.body;
let journal_entry_new = new Object();
journal_entry_new.date = date;
journal_entry_new.temp = temp + "°C";
journal_entry_new.content = content;
idx_entry = String("entry_" + idx)
idx = idx + 1
projectData[idx_entry] = JSON.stringify(journal_entry_new);
console.log(projectData)
res.send(projectData)
console.log("Post sucessful.")
}
router.post('/', cache('2 minutes'), async (req, res, next) => {
const postObject = needle.post('/addData', req.body, sendForecastData)
return postObject;
})
function readData(req, res) {
res.send(projectData)
console.log(projectData)
console.log("Read sucessful.")
}
router.get('/readData', readData)
module.exports = router
This is my app.js
//Event-Listener
document.getElementById('generate').addEventListener('click', performAction);
//Declare Fetch Function
//User Input
const the_date = document.getElementById('date');
const temp = document.getElementById('temp');
const content = document.getElementById('content');
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = (d.getMonth() + 1) + "." + (d.getDate()) + '.' + (d.getFullYear());
//Proxy
const fetchWeather = async (zipcode) => {
const url = `/api?q=${zipcode}`
const res = await fetch(url)
const data = await res.json()
console.log(data)
return data;
}
const postData = async (url, data) => {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
try {
const data = await response.json();
return data
}
catch (error) {
console.log("error", error);
}
}
const readData = async () => {
const request = await fetch('/readData');
try {
// Transform into JSON
const readData = await request.json()
return readData
} catch (error) {
console.log("error", error);
}
}
const UpdateUI = async (data) => {
console.log("Data received:")
console.log(data)
console.log("Date: " + data[Object.keys(data)[0]])
console.log("Temp: " + data[Object.keys(data)[1]])
console.log("Content: " + data[Object.keys(data)[2]])
document.getElementById('temp').innerText = "Temperature is: " + data[Object.keys(data)[1]]
document.getElementById('date').innerText = "Date is: " + data[Object.keys(data)[0]]
document.getElementById('content').innerText = "Feeling is: " + data[Object.keys(data)[2]]
console.log("Updated UI")
}
function performAction(e) {
//Check if user input is available
if (document.getElementById('zip').value == "") {
alert("Please type in a zipcode, then I will know where to look up the weather for
you!");
return
}
//Feeling now
let zipcode = (document.getElementById('zip').value).toString()
let feeling_now = (document.getElementById('feelings').value).toString()
fetchWeather(zipcode)
.then(data => {
/*let temp_k = parseFloat(data.list[0].main.temp)*/
/*let temp_c = String((temp_k - 273.15).toFixed(2)) + " °C"*/
let temp_c = parseFloat(data.main.temp) + " °C"
let feeling_now = (document.getElementById('feelings').value).toString()
console.log(temp_c)
console.log(newDate)
console.log(feeling_now)
console.log({ date: newDate, temp: temp_c, content: feelings.value })
return { date: newDate, temp: temp_c, content: feelings.value }
}).then(data => {
postData('/addData', data);
return data
})
.then(data => {
readData('/readData');
return data
})
.then(data => UpdateUI(data))
console.log(feeling_now)
return;
}
My UI is updated, however I get the following error and cannot access localhost:5000/addData - can you help why this is the case?
Defined the routes in the backend, however cannot call them from frontend

Save to file results in async function

I got a simple async function where I "scrape" site from URLs.
Everything works fine, but now I want to save results into my txt file.
I tried to do simply array where I able to push every result also errors;
Now I got a problem where should I do write to file.
I tried putting it to a separated function then do await function inside my async function but function with write to file i always fired first.
There is full code
const https = require("https");
const fs = require("fs");
const readline = require("readline");
const path = require("path");
let urls = [];
let results = [];
(async function readUrls() {
const fileStream = fs.createReadStream("urls.txt");
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity,
});
for await (let line of rl) {
urls.push(line);
}
for await (let url of urls) {
https
.get(url, (res) => {
const {
statusCode
} = res;
const contentType = res.headers["content-type"];
let error;
if (statusCode !== 200) {
error = new Error("Request Failed.\n" + `Status Code: ${statusCode}`);
}
if (error) {
const firstPath = url.split("/")[7];
//there is array
results.push(firstPath);
//--------------
console.error("data : " + firstPath + " - " + " nothing found");
res.resume();
return;
}
res.setEncoding("utf8");
let rawData = "";
res.on("data", (chunk) => {
rawData += chunk;
});
(async () => {
await res.on("end", () => {
try {
const parsedData = JSON.parse(rawData);
const parsedResult = parsedData["data"]["id"] + " - " + parsedData["data"]["price"];
//there is array
results.push(parsedResult);
//--------------
console.log("data : " + parsedData["data"]["id"] + " - " + parsedData["data"]["price"]);
} catch (e) {
console.error(e.message);
}
});
})();
})
.on("error", (e) => {
console.error(`Got error: ${e.message}`);
});
}
})();
There is my simple function to write into file
fs.writeFile('result.txt', results, +(new Date()), function (err) {
if (err) {
console.log("Error occurred", err);
}
console.log("File write successfull");
});
I tried do something
async function secondFunction(){
await firstFunction();
// wait for firstFunction...
};
What I want to achive? I want to scrape every url from my text file and get ID and Price
( this is simple JSON response into browser no html - it works )
At the end I want to save everything into text file.
I made a version of your code that uses node-fetch to call the urls. I prefer this one as it is similar to what one can use on the web
To use it you should install it:
npm install node-fetch
const fetch = require("node-fetch"); // I prefer to use node-fetch for my calls
const fs = require("fs");
const readline = require("readline");
const path = require("path");
let urls = [];
let results = [];
(async function readUrls() {
const fileStream = fs.createReadStream("urls.txt");
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity,
});
for await (let line of rl) {
urls.push(line);
}
// Make the calls one after the other
for (let url of urls) {
try {
// We can call the urls with node-fetch and await the response
const res = await fetch(url);
const { status } = res;
let error;
if (status !== 200)
error = new Error("Request Failed.\n" + `Status Code: ${statusCode}`);
if (error) {
const firstPath = url.split('/')[7];
results.push(firstPath);
console.error("data : " + firstPath + " - " + " nothing found");
// As we are inside a loop here, we use continue instead of return
continue;
}
try {
// Here we try to take the response as json
const parsedData = await res.json();
const parsedResult = parsedData["data"]["id"] + " - " + parsedData["data"]["price"];
//there is array
results.push(parsedResult);
//--------------
console.log(`Data: ${parsedResult}`);
} catch (e) {
// In case we can't get the response as json we log the error
console.error(e.message);
}
} catch (httpError) {
//This is for when the call to fetch fails for some reason
console.error(httpError.message);
}
}
// Here we join the results to a string so that we can save it properly to the file
const resultAsText = results.join("\n");
// Then after all the urls are processed we can write them to a file
fs.writeFile('result.txt', resultAsText, 'utf8', function (err) {
if (err) {
console.log("Error occurred", err);
} else {
console.log("File write successfull");
}
});
})();

CypressIO Returning string value from cy.task() using cy.wrap() gives error "cy is not defined"

In cypress /plugins/index.js I have code to query oracleDB
module.exports = (on, config) => {
on('task', {
'registration': async (email) => {
const oracledb = require('oracledb');
oracledb.initOracleClient({libDir: './oracleClient'});
let result;
let connection;
connection = await oracledb.getConnection( {
user : process.env.ORACLEDB_USER,
password : process.env.ORACLEDB_PASSWORD,
connectString : "localhost/STORE"
});
result = await connection.execute(
"select ..."
);
console.log(result.rows)
var extractedUrlText = JSON.stringify((await result).rows).extract('/VerifiedRegistrationFormView','\"');
console.log('Extracted URL: \r\n' + extractedUrlText);
return cy.wrap(extractedUrlText);
}
});
}
This returns the correct extracted URL in Node terminal.
But then in my cypress test, when I try to use that extractedUrlText string value i'm getting error cy is not defined:
it('Register a new user', () => {
cy.task('registration', emailAddress, { timeout: 10000 }).then(value => cy.log(value)) // cy is not defined
})
I use a similiar approach to use a returned value from support/commands.js Cypress.Commands.add() and it works there, but not from cy.task() using cy.wrap()
My working solution:
/plugins/index.js extended from above code:
var extractedUrlText = JSON.stringify((await result).rows).extract('/VerifiedRegistrationFormView','\"');
console.log('Extracted NODE URL: \r\n' + extractedUrlText);
return extractedUrlText
}
In spec file:
let extractedUrl;
cy.task('registration', emailAddress).then(value => {
extractedUrl = value;
cy.log('Extracted CY URL: ' + extractedUrl)
})
Result:

Getting TypeError: FabricUserControllers is not a constructor which can not be catch

I am new to node.js and Javascript.
I have two javascript files "FabricUserController.js" and "UserController.js". So I have create the class in "FabricUserController.js" and export it into "UserController.js".
I am integrate the GetAll fucntion of "FabricUserController.js" to "UserController.js" in GetAllProduce fucntion.
I am trying run the below code however its giving me "TypeError: FabricUserControllers is not a constructor" error which is not handle in try catch{} block
Please see below code
let FabricUserControllers3 = require("./FabricUserController");
GetAllProduce: function (req, res, next) {
try{
let output = {};
var resArray = new Array();
let VZID = req.body.username;
console.log('test', 'GetAllProduce')
console.log('USername', VZID)
MongoClient.connect(config.Database.TEST.connectString, function (err, client) {
if (err) {
let connError = new Error(500, "Error connecting to TEST database", err);
res.status(connError.status).json(connError);
} else {
let query = {};
client.db(config.Database.TEST.dbName).collection("Produce").find(query).toArray(function (err, response) {
console.log(response);
if (err) {
let roleError = new Error(500, "Error getting Produce information", err);
res.status(500).json(roleError);
} else if (response.length > 0) {
//DO someting here
//FabricUserControllers3 = {};
FabricUserControllers3 = new FabricUserControllers();// getting issue here
FabricUserControllers3.GetAll((VZID), (response) => {
console.log("data result", result)
res.status(200).json(response);
client.close();
})
} else {
output.message = "Produce doesn't exist";
res.status(409).json(output);
client.close();
}
});
}
});
}catch(e){
if (e instanceof TypeError){
console.log('error1', e.message);
printError(e,true);
}else{
console.log("error2", e.message);
printError(e, false);
}
}
},
FabricUserController.js
'use strict';
const {
FileSystemWallet,
Gateway
} = require('fabric-network');
const fs = require('fs');
const path = require('path');
var MongoClient = require('mongodb').MongoClient;
var Client = require('node-rest-client').Client;
var client = new Client();
const configPath = path.resolve(__dirname, '..', 'config', 'Config.json');
const configJSON = fs.readFileSync(configPath, 'utf8');
const config1 = JSON.parse(configJSON);
var connection_file = config1.connection_file;
var appAdmin = config1.appAdmin;
var gatewayDiscovery = config1.gatewayDiscovery;
var appAdminSecret = config1.appAdminSecret;
var orgMSPID = config1.orgMSPID;
var caName = config1.caName;
const ccpPath = path.resolve(__dirname, '..', 'config', 'connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
let response = {};
class FabricUserControllers {
constructor() {
console.log("constructer called")
}
async ProduceRegistration(Username, produceid, callback) {
// Create a new file system based wallet for managing identities.
try {
const setAsyncTimeout = (cb, timeout = 0) => new Promise(resolve => {
setTimeout(() => {
cb();
resolve();
}, timeout);
});
let query2 = {}
query2.PRODUCEID = produceid;
// console.log('PRODUCEID',produceid)
var PRODUCE = {};
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
console.log('Username', Username)
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(Username);
if (!userExists) {
console.log('An identity for the user: ' + Username + ' does not exist in the wallet');
console.log('call the registerUser before retrying');
response.data = null;
response.httpstatus = 400;
response.message = `An identity for the ${Username} does not exist in the wallet`;
return response;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: Username,
discovery: {
enabled: false,
asLocalhost: true
}
});
///
MongoClient.connect(config.Database.TEST.connectString, function (err, client) {
if (err) {
// let connError = new Error(500, "Error connecting to TEST database", err);
response.data=null;
response.httpstatus = 500;
response.message = "Error connecting to TEST database :" + err;
// res.status(connError.status).json(connError);
return response;
} else {
client.db(config.Database.TEST.dbName).collection("Produce").find(query2).toArray(function (err, docs) {
if (err) {
response.httpstatus = 500;
response.message = "Error with DB :" + err;
return response;
}
else{
console.log("blockchain_status", docs[0].blockchain_status)
console.log('Role name DB',docs);
console.log('Role name DB1',docs[0]);
if(docs[0].STATUS)
PRODUCE.produceid = docs[0].PRODUCEID;
PRODUCE.produceName = docs[0].PRODUCE;
PRODUCE.farmLocation = docs[0].FARMLOCATION;
PRODUCE.plantingDate = docs[0].PLANTINGDATE;
PRODUCE.harvestDate = docs[0].HARVESTDATE;
PRODUCE.status = docs[0].STATUS;
PRODUCE.produceQuantites = docs[0].VARIETY;
PRODUCE.gapInfo = docs[0].GAP;
PRODUCE.farmerID = docs[0].farmerID;
console.log('Produce', PRODUCE);
const doStuffAsync = async () => {
setAsyncTimeout(async () => {
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('dfarmchannel');
// Get the contract from the network.
const contract = network.getContract(config1.chaincodeName);
var args = JSON.stringify(PRODUCE)
console.log("type of arg", typeof (args));
// Submit the specified transaction.
// console.log('produceID', args.produceID);
if(args==null || args==''){
console.log('Server not responding please try again');
}else
{
const result = await contract.submitTransaction('ProduceRegistration', args);
var argsJson = JSON.parse(result)
// console.log('result', argsJson)
// console.log('result1', result)
if(argsJson.produceID !="" && argsJson.produceID !=null && argsJson.produceID !="undefined" && argsJson.produceID !=undefined){
// // return false;
response.data = result
response.httpstatus = 200;
response.message = `Transaction has been submitted ansd successfull with Result :${result}`;
return callback(response);
// console.log('result before', response);
// console.log('Transaction has been submitted ansd successfull with Result :' + result);
}else{
console.log('blockchain server not responed')
// return false
response.httpstatus = 500;
response.message = `Please enter produce ID :`;
return response;
}
}
}, 4000);
};
doStuffAsync();
}
client.close();
})
}
})
await gateway.disconnect();
}
catch (error) {
// if(error) throw error;
response.error = error;
response.httpstatus = 500;
response.message = "Failed to enroll admin due to above error";
return response;
}
};
}
module.exports = FabricUserControllers;
#Abhirock, on your main file you have:
let FabricUserControllers3 = require("./FabricUserController");
FabricUserControllers3 = new FabricUserControllers();// getting issue here
You are trying to override FabricUserControllers3 creating a new object FabricUserControllers but you are not importing it. Try next solution to see if it solves your problem:
const FabricUserController = require("./FabricUserController");
const fabricUserControllers3 = new FabricUserController();
Hope it helps :))

Undefined results when using imported custom nodejs module

I am trying to search my local db for a user by email, but when I try to reference a function that does that from a different js file, via an import, I get undefined results. I have searched a bit on Stack about this issue I am having, and heard of something referred to as a callback, is this something that I would need to implement? If so could you point me to an example ?
Thanks in advance!
Here is my code that is exported (db.js file) :
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost:7687", neo4j.auth.basic("neo4j", "neo4j"));
var session = driver.session();
exports.findEmail = (email) => {
// console.log('hi');
session
.run("MATCH (a:Person) WHERE a.email = {email} RETURN a.name AS name, a.email AS email, a.location AS location", {
email: email
})
.then((result) => {
let result_string = '';
result.records.forEach((record) => {
console.log(record._fields);
result_string += record._fields + ' ';
});
return result_string;
})
.catch((e) => {
return ('error : ' + JSON.stringify(e));
})
}
Here is my code calling the export : (test.js)
var tester = require('./db.js');
let temp = tester.findEmail("testemail#yahoo.com");
console.log(temp);
The thing is that JS is asynchronous, and you using it as it is synchronous code.
Can you try this one, should work:
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost:7687", neo4j.auth.basic("neo4j", "neo4j"));
var session = driver.session();
const findEmail = (email, callback) => {
console.log('hi :', email);
session
.run("MATCH (a:Person) WHERE a.email = {email} RETURN a.name AS name, a.email AS email, a.location AS location", {
email: email
})
.then((result) => {
let result_string = '';
result.records.forEach((record) => {
console.log(record._fields);
result_string += record._fields + ' ';
});
return callback(null, result_string);
})
.catch((e) => {
return callback('error : ' + JSON.stringify(e)));
})
}
module.exports = {
findEmail
};
Then in test.js:
var tester = require('./db');
tester.findEmail("testemail#yahoo.com", (err, temp) => {
if (err) return console.error(err);
console.log(temp);
} );
The idea behind this is that all the flow in db file is asynchronous.
So in order to catch result you need to pass the function, callback, which will be triggered when the ansynchronous flow is done.

Categories

Resources