Node.js & Redis & For Loop with bluebird Promises? - node.js

i want a function that makes a new JSON Object that looks so :
{ T-ID_12 : [{ text: "aaaaa", kat:"a" }], T-ID_15 : [{ text: "b", kat:"ab" }], T-ID_16 : [{ text: "b", kat:"ab" }] }
This { text: "aaaaa", kat:"a" } in thesenjsondata and this T-ID_12 is an entry of the array Thesen_IDS. And my solution so far is :
function makeThesenJSON(number_these, Thesen_IDS){
var thesenjsondata;
var thesenids_with_jsondata = "";
for (i = 0; i < number_these; i++ ){
db.getAsync(Thesen_IDS[i]).then(function(res) {
if(res){
thesenjsondata = JSON.parse(res);
thesenids_with_jsondata += (Thesen_IDS[i] + ' : [ ' + thesenjsondata + " ], ");
}
});
}
var Response = "{ " + thesenids_with_jsondata + " }" ;
return Response;
}
I know, that the for-loop is faster then the db.getAsync(). How can i use the bluebird promises with redis right, so that the return value has all data that i want ?

You just create an array of promises out of Redis calls, then use Bluebird's Promise.all to wait for all to come back as an array.
function makeThesenJSON(number_these, Thesen_IDS) {
return Promise.all(number_these.map(function (n) {
return db.GetAsync(Thesen_IDS[n]);
}))
.then(function(arrayOfResults) {
var thesenids_with_jsondata = "";
for (i = 0; i < arrayOfResults.length; i++) {
var res = arrayOfResults[i];
var thesenjsondata = JSON.parse(res);
thesenids_with_jsondata += (Thesen_IDS[i] + ' : [ ' + thesenjsondata + " ], ");
}
return "{ " + thesenids_with_jsondata + " }";
})
}
Note how this function is Async because it returns a Promise that will eventually resolve to a string. So you call it like this:
makeThesenJSON.then(function (json) {
//do something with json
})

Related

My save data to MongoDB not functioning, is it because my searching is wrong?

I'm trying to make a comparison function. If the value that I search is not exist, the new value will be save to the database. But all I get is 0 new data found. So the system decides to not save the data. Is my searching wrong?
This is my code:
var count = 0;
for (var t = 1; t < 151; t++) {
var searching = JobsSchema.find({ jobName: name[t], company: company[t] })
if (searching == null) {
count = count + 1;
var newJobs = new JobsSchema({
"jobName": name[t],
"country": country[t],
"company": company[t],
"jobType": type[t],
"salary": salary[t],
"skills": skills[t],
"jobDesc": desc[t],
"jobReq": req[t],
"jobResponsibility": resp[t],
"industry": industry[t],
})
newJobs.save(function (err, result) {
if (err) {
console.log(err);
}
})
}
}
console.log(count + " new data found.");
You should await your find function.
Also, change it to findOne to return a single instance of the JobsSchema and await the save call as well.
Finally you will need to wrap the code into an async function:
const saveData = async () => {
var count = 0;
for (var t = 1; t < 151; t++) {
var searching = await JobsSchema.findOne({
jobName: name[t],
company: company[t],
});
if (!searching) {
count = count + 1;
var newJobs = new JobsSchema({
jobName: name[t],
country: country[t],
company: company[t],
jobType: type[t],
salary: salary[t],
skills: skills[t],
jobDesc: desc[t],
jobReq: req[t],
jobResponsibility: resp[t],
industry: industry[t],
});
await newJobs.save();
}
}
console.log(count + ' new data found.');
};
saveData();

Edit a JSON object

I retrieved a JSON object from a local database, I want to edit a value (invItems) and add a new value to it (filed[filed.invItems]), then upload it back to the database, but it does not seem to work (the JSON does not seem to change)
async function invPut(itemID, message) {
var filed = await frenzyDB.getKey(id + "_invcache");
console.log("Before: " + filed)
newInvItems = filed.invItems + 1;
filed.invItems = newInvItems;
filed[filed.invItems] = itemID;
console.log("After: " + filed);
await frenzyDB.addKey(id + "_invcache", filed)
}
Console Output:
Before: {"invItems":0}
After: {"invItems":0}
It shows no errors, but the JSON doesnt change. Am I doing something wrong? If so, what can I do to fix it?
Thanks for all your help!
Notes:
frenzyDB is just a javascript file that deals with a standard REPL.it Database
Code of frenzyDB:
const Database = require("#replit/database")
const db = new Database()
async function addKey(key, value) {
await db.set(key, value).then(() => {return;});
}
async function getKey(key) {
return await db.get(key).then(value => {return value;});
}
function listAllKeys() {
db.list().then(keys => {return keys;});
}
async function hasKey(key) {
var keys = await listAllKeys();
if (keys.includes(key)) {
return true;
} else {
return false;
}
}
async function removeKey(key) {
await db.delete(key).then(() => {return;});
}
module.exports = {
addKey,
getKey,
listAllKeys,
hasKey,
removeKey
};
Edit: Latest code:
async function invPut(itemID, message) {
await init(message.author.id);
var filed = await frenzyDB.getKey(message.author.id + "_invcache");
console.log(filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(result);
frenzyDB.addKey(message.author.id + "_invcache", result)
message.reply("A **"+ itemIDs[itemID].name + "** was placed in your inventory");
return true;
}
EDIT 2: Latest Console Output:
{ '4': 3, invItems: 5 }
{ '5': 3, invItems: 6 }
Any help will be appreciated!
Thanks
Try this
// Demo Data
const itemID = 10;
var filed = { "invItems" : 0 };
// Real function
console.log("Before: " + JSON.stringify(filed));
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + JSON.stringify(result));
The result I get is
Before: {"invItems":0}
After: {"0":10,"invItems":1}
You would then of course use result to store the data away in the DB.
async function invPut(itemID, message) {
// Typo?
var filed = await frenzyDB.getKey(itemID + "_invcache");
console.log("Before: " + filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + result);
// Typo?
await frenzyDB.addKey(itemID + "_invcache", result)
}
Answer Edit:
const result = { ...filed };
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(JSON.stringify(result));
maybe this will help you
const json = fs.readFileSync(`${__dirname}/data/data.json`, "utf-8");
const inputData = JSON.parse(json);
inputData.push({input: 'front'}) // creates new element for data.json
-------------------------------------------
array.push({front: 'front', back: 'back'});

Using node.js for-loop index in a coinbase-api callback function

I am new to node.js and i am trying to make a simple script that will connect to the coinbase-api and get the current price of whatever markets are defined in the MARKET array.
The problem i am having is that the for-loop that iterates through the array is asynchronous and the callback function is not getting the correct index value for the array.
The two main solutions i have found are to use promises or force the loop to wait. I think i need to be using promises rather than forcing the for loop to wait but honestly i have failed to implement a solution either way. I have found may example of promises but i just cant seem to figure out how to implement them into my script. I would appreciate any help.
const coinbaseModule = require('coinbase-pro');
const COINBASE_URI = 'https://api-public.sandbox.pro.coinbase.com';
// const MARKET = ['BTC-USD'];
const MARKET = ['BTC-USD', 'ETH-BTC'];
let askPrice = [null, null];
let averagePrice = [null, null];
let tickerCount = null;
const getCallback = (error, response, data) =>
{
if (error)
return console.log(error);
if ((data!=null) && (data.ask!=null) && (data.time!=null))
{
askPrice[tickerCount] = parseFloat(data.ask);
if (averagePrice[tickerCount]===null)
{
averagePrice[tickerCount] = askPrice[tickerCount];
console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6));
}
else
{
averagePrice[tickerCount] = (averagePrice[tickerCount] * 1000 + askPrice[tickerCount]) / 1001;
console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6) + " average price: "+ averagePrice[tickerCount].toFixed(6));
}
}
}
setInterval(() =>
{
console.log('\n');
publicClient = new coinbaseModule.PublicClient(COINBASE_URI);
for (tickerCount = 0; tickerCount < MARKET.length; tickerCount++)
{
publicClient.getProductTicker(MARKET[tickerCount], getCallback);
}
}, 10000);
I was able to figure out how to use promises with trial and error from the helpful examples on the Mozilla Developer Network. I am sure i am making some mistakes but at least it is working now. Another little bonus is that i was able to remove a global.
const coinbaseModule = require('coinbase-pro');
const COINBASE_URI = 'https://api-public.sandbox.pro.coinbase.com';
// const MARKET = ['BTC-USD'];
const MARKET = ['BTC-USD', 'ETH-BTC'];
let askPrice = [null, null];
let averagePrice = [null, null];
function getProductTicker(tickerCount) {
return new Promise(resolve => {
publicClient.getProductTicker(MARKET[tickerCount],function callback(error, response, data){
if (error)
return console.log(error);
if ((data!=null) && (data.ask!=null) && (data.time!=null))
{
askPrice[tickerCount] = parseFloat(data.ask);
if (averagePrice[tickerCount]===null)
{
averagePrice[tickerCount] = askPrice[tickerCount];
console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6));
}
else
{
averagePrice[tickerCount] = (averagePrice[tickerCount] * 1000 + askPrice[tickerCount]) / 1001;
console.log(MARKET[tickerCount] + " ask price: " + askPrice[tickerCount].toFixed(6) + " average price: "+ averagePrice[tickerCount].toFixed(6));
}
resolve();
}
});
});
}
setInterval( async () =>
{
console.log('\n');
publicClient = new coinbaseModule.PublicClient(COINBASE_URI);
for (var tickerCount = 0; tickerCount < MARKET.length; tickerCount++)
{
await getProductTicker(tickerCount);
}
}, 10000);

How to iterate a loop in nodejs

I have a json variable
var a = { Account: [ 'Name', 'Site', 'BillingState', 'Phone', 'Type', 'Owner.Alias' ],
Contact: [ 'Name1', 'Site1' ] }
and i am iterating loop like this
app.post('/', function (req, res) {
a = req.body.table_structure
b = createSelectQuery(a) res.send(b) // this return only "FROM CONTACT" })
Where i have created another function hoping i could in return get the desired string but the loop went async
function createSelectQuery(a){
var selectQuery = "Select "
var obj = JSON.parse(a);
for (var c in obj){
for (var d in obj[c]){
selectQuery += obj[c][d] + ', '
}
selectQuery = "FROM "+c
}
return selectQuery
}
I am expecting result "SELECT Name, .. etc from Account but getting
only FROM Account as output
Try this
function createSelectQuery(a){
var selectQuery = "Select ";
var obj = JSON.parse(a);
for (var c in obj) {
selectQuery += obj[c].join(", ") + " FROM " + c;
}
return selectQuery;
}
you need to use callback which will make your looping synchronous
I belive because in JSON file 'Account' is array and you try to loop in to it as if it was an object. Try :
function createSelectQuery(a){
var selectQuery = "Select "
var obj = JSON.parse(a);
for (var c in obj){
for (var d=0; d < obj[c].length; d++){
selectQuery += obj[c][d] + ', '
}
selectQuery = "FROM "+c
}
return selectQuery
}
Instead of loop, you can try join the string using arr.join() and then append the string with Object.keys. That will do the trick
var selectQuery = "Select ";
var a = { Account: [ 'Name', 'Site', 'BillingState', 'Phone', 'Type', 'Owner.Alias' ]};
var obj = a;
var arr = obj['Account'];
var joinStr = arr.join(',').toString();
selectQuery = selectQuery +" "+joinStr +" FROM "+Object.keys(a);
console.log(selectQuery);

Sequelize, Raw Query by daterange

I use "sequelize": "^2.0.0-rc3" with pg (postgresql), in this moment i am trying to do a raw query with date range but sequelize don't return data.
When I run the same query in postgresql db get correct results. Please Help Me.
In sequilize:
// Init main query
var query = "SELECT * FROM" + '"Calls"' +
" WHERE " + '"EquipmentId"' + " = 1" +
" AND " + '"initDate"' + " >= " + "'2015-02-05 14:40' " +
" AND " + '"endDate"' + " <= " + " '2015-02-05 15:00' ";
global.db.sequelize.query(query)
.then(function(calls) {
console.log(calls);
})
.error(function (err) {
console.log(err);
});
In console of node server I get.
Executing (default): SELECT * FROM "Calls" WHERE "EquipmentId" = 1 AND "initDate" >= '2015-02-05 14:40' AND "endDate" <= '2015-02-05 15:00'
But empty array calls...
Try this:
var query = ' \
SELECT * FROM "Calls" \
WHERE "EquipmentId" = :EquipmentId \
AND "initDate" >= :initDate \
AND "endDate" <= :endDate; \
';
global.db.sequelize.query(query, null, {raw: true}, {
EquipmentId: 1,
initDate: new Date('2015-02-05 14:40'),
endDate: new Date('2015-02-05 15:00')
})
.then(function(calls) {
console.log(calls);
})
.error(function (err) {
console.log(err);
});
You can also use sequelize function like findAll
Model.findAll(
where : {
gte:sequelize.fn('date_format', initDate, '%Y-%m-%dT%H:%i:%s'),
lte:sequelize.fn('date_format', endDate, '%Y-%m-%dT%H:%i:%s')
}
)
To get a result between two date ranges you just need to do this.
let whereClause = {
where: { $and: [
{ time: { [ Op.gte ]: req.query.start_time } },
{ time: { [ Op.lte ]: req.query.end_time } }
]
}
};
await model_name.findAll(whereClause);

Resources