node js redis loop through each hash key value - javascript

I am very new to redis & node and at the moment I am trying to loop through some test hash keys that i have created and print out to screen the results. Here is the result I expect to see:
{ "aaData": [['Tim Osbourne'],['Joe Bloggs'],['John Doe'],['Perry Coke'],['Will Holmes'],['Steven Smith']}
but instead I get this result:
{ "aaData": [[],[],[],[],[],[],]}'Tim Osbourne','Joe Bloggs','John Doe','Perry Coke','Will Holmes','Steven Smith',
Here is my code:
app = require('../app');
var redis = require("redis"),
client = redis.createClient();
routes = require('./');
var key_types = '';
client.keys("*", function (err, all_keys) {
key_types += '{ "aaData": [';
all_keys.forEach(function (key, pos) { // use second arg of forEach to get pos
key_types += "[";
client.hmget([key, 'Owner of space'], function(err, field_val){
key_types = key_types + "'" + field_val + "',";
});
key_types += "],";
});
key_types += "]}";
});
app.get('/table_data', function(req, res){
res.render('table_data', { keys: key_types});
});

You should not do a keys *
It does not work because hmget is asynchronous, you should use the async module (async.map) for that.
What is the goal of [key, 'Owner of space'] since 'Owner of space' will always yield the same result?

Related

NodeJS SQL Server - Running multiple queries with Async

I'm attempting to run two separate queries in a NodeJS Lambda Function. The first inserts a single record, and will return an order number used in the subsequent queries. The second query needs to insert n records (order items), so I've been trying to execute those utilizing the async node library as you can see below.
I'm running into issues where it's either not executing those queries at all, or is only inserting a single record versus n records. I'm feeding it right now with an API request, so the referenced items array should have two indexes in it, resulting in two iterations.
const sql = require('mssql');
const async = require('async');
(function() {
// ——- Database support ——- //
exports.handler = function(event, context, callback)
{
const config = {
user: 'my_user',
password: 'my_pass',
server: 'my_serv',
database: 'my_db',
options: {
encrypt: true
}
};
// Request Body
var body = event;
var items = body[1]["items"];
var addDateTimeRaw = body[1]["created_at"];
var splitDateTime = addDateTimeRaw.split(" ");
// SPROC params
var CustomerNumber = "1234";
var OrderDateString = splitDateTime[0];
var ShipVia = "UPS";
var FOB = "null";
var PaymentTerms = "CREDIT CARD";
var Discount = "0";
var OrderAmount = body[1]["total_price"].cents;
var PONumber = body[1]["_id"];
var Comment = "I am a comment";
var SalesPerson = "WA";
var IsShippingSameAsBilling = "X";
var TaxableAmount = body[1]["total_value"].cents;
var TaxState = "my_state";
var AddDate = splitDateTime[0];
var AddTime = splitDateTime[1];
var WebOrderNumber = body[1]["_id"];
sql.connect(config, (err) => {
if (err) {
console.log(err);
callback(err);
} else {
const req = new sql.Request();
req.query('EXEC InsertOrder #CustomerNumber = "' + CustomerNumber + '", #OrderDateString = "' + OrderDateString + '", #ShipVia = "' + ShipVia + '", #FOB = "' + FOB + '", #PaymentTerms = "' + PaymentTerms + '", #Discount = "' + Discount + '", #OrderAmount = "' + OrderAmount + '", #PONumber = "' + PONumber + '", #Comment = "' + Comment + '", #SalesPerson = "' + SalesPerson + '", #IsShippingSameAsBilling = "' + IsShippingSameAsBilling + '", #TaxableAmount = "' + TaxableAmount + '", #TaxState = "' +TaxState + '", #AddDate = "' + AddDate + '", #AddTime = "' + AddTime + '", #WebOrderNumber = "' + WebOrderNumber + '";', (error, result) => {
if (error) {
console.log(error);
callback(error);
} else {
var OrderNumber = result.recordset[0].sono;
insertOrderItems(OrderNumber);
sql.close();
context.succeed(result.recordset)
return JSON.stringify(items);
}
});
function insertOrderItems(OrderNumber) {
async.forEachOf(items, function (item, i, inner_callback){
//var itemNumber = item["sku"];
var ItemNumber = "5678";
var DiscountPercent = "0";
var TaxRate = "6";
var Quantity = item["quantity"];
var ItemSequence = i + 1;
var CustomerMemo = "I am a memo";
var UnitPrice = "6.00";
var ssql = 'EXEC InsertOrderItems #OrderNumber = "' + OrderNumber + '", #ItemNumber = "' + ItemNumber + '", #DiscountPercent = "' + DiscountPercent + '", #TaxRate = "' + TaxRate + '", #Quantity = "' + Quantity + '", #ItemSequence = "' + ItemSequence + '", #CustomerMemo = "' + CustomerMemo + '", #UnitPrice = "' + UnitPrice + '";';
req.query(ssql, function(err, members, fields){
if(!err){
console.log(members);
//context.succeed(members.recordset)
inner_callback(null);
} else {
console.log("Error while performing Query");
inner_callback(err);
};
});
}, function(err){
if(err){
//handle the error if the query throws an error
callback(err);
}else{
//whatever you wanna do after all the iterations are done
callback(null);
}
});
}
}
});
sql.on('error', (err) => {
console.log(err);
callback(err);
});
};
}());
Why might that function call to the async SQL query not be executing? I'm attempting to keep the same SQL connection open for both of the executed queries.
The async is not a main issue. I patched some places but it still worse.
Why do you not learn step-by-step?
const sql = require('mssql');
const async = require('async');
const config = { ... };
exports.handler = function(event, context, callback) {
// Use default object with props or check existing of every props
var body = (event && event[1]) instanceof Object ? event[1] : {items: [], created_at: ' ', _id: ...};
var items = body.items || []; // Always use default value
var [addDate, addTime] = (created_at || '').split(' '); // Use destructuring assignment
// SPROC params
var CustomerNumber = "1234";
var OrderDateString = splitDateTime[0];
var ShipVia = "UPS";
var FOB = "null";
var PaymentTerms = "CREDIT CARD";
var Discount = "0";
var OrderAmount = parseFloat((body.total_price || {}).cents) || 0; // total_price can be non-object and it'll fall your app
var PONumber = body[1]["_id"];
var Comment = "I am a comment";
var SalesPerson = "WA";
var IsShippingSameAsBilling = "X";
var TaxableAmount = body[1]["total_value"].cents;
var TaxState = "my_state";
var WebOrderNumber = body._id;
sql.connect(config, (err) => {
// Early quit to avoid {}-ladder
if (err)
return callback(err);
const req = new sql.Request();
// Never do like this. Read about sql-injection. Use placeholders.
req.query('EXEC ost_InsertOrder #CustomerNumber = "' + ..., (err, result) => {
if (err)
return callback(err);
var OrderNumber = result.recordset.length && result.recordset[0].sono; // You must be sure that result has rows
// You should read about async-code
insertOrderItems(OrderNumber); // Here you start to insert items
sql.close(); // But before it'll success you close connection.
context.succeed(result.recordset);
// I didn't see definition of items.
// Return? For what?
return JSON.stringify(items);
});
...
}
});
sql.on('error', callback);
};

NodeJS and Express; callback on connection query completed

I am trying to insert several records in a mysql database and I need to get each record's ID and send it back to the client. The code I'm using:
app.post('/saveLesson',function(req, res){
var idArray = [];
let sections = JSON.parse(req.body.sections);
for (let i = 0; i < sections.length; i++) {
let sql = 'INSERT INTO sections (title, content, duration) VALUES ("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '");';
connection.query(sql,
function (error, result) {
if (error) throw error;
idArray.push(result.insertId);
console.log('array in the loop: ' + idArray);
}
);
}
console.log('array out of the loop: ' + idArray);
res.send(idArray);
});
The problem is that the .query method seems to be asynchronous and the following code is executed before the idArray is actually populated:
console.log('array out of the loop: ' + idArray);
res.send(idArray);
What would be the appropriate way to deal with this issue?

Write javascript array elements to file

I am trying to have a node js script write some coordinates to a csv file for use in a Newman CLI script. I have the following:
const axios = require('axios');
var move_decimal = require('move-decimal-point');
var sLat = 45.029830;
var sLon = -93.400891;
var eLat = 45.069523;
var eLon = -94.286001;
var arrLatLon = []
axios.get('http://router.project-osrm.org/route/v1/driving/' + sLon + ',' + sLat + ';' + eLon + ',' + eLat + '?steps=true')
.then(function (response) {
for (let i = 0; i < response.data.routes[0].legs.length; i++) {
//console.log(response.data)
for (let ii = 0; ii < response.data.routes[0].legs[i].steps.length; ii++) {
//console.log('leg ' + i + " - step " + ii + ": " + response.data.routes[0].legs[i].steps[ii].maneuver.location[1] + "," + response.data.routes[0].legs[i].steps[ii].maneuver.location[0]);
// Declaring Latitude as 'n' & Longitude as 'nn' for decimal calculations
var n = response.data.routes[0].legs[i].steps[ii].maneuver.location[1]
var nn = response.data.routes[0].legs[i].steps[ii].maneuver.location[0]
// Latitude calculatiuons to make 'lat' values API friendly
var y = move_decimal(n, 6)
var p = Math.trunc(y);
// Longitude calculations to make 'lon' values API friendly
var yy = move_decimal(nn, 6)
var pp = Math.trunc(yy);
arrLatLon.push(p + "," + pp);
}
console.log(arrLatLon)
}
})
I have been looking through and trying numerous different tutorials/code snippets regarding writing the array elements from arrLatLon to an output file on my local machine, but none have been successful. The current code outputs the lat,lon correctly, console.log(arrLatLon) outputs:
[ '45029830,-93400894',
'44982812,-93400740',
'44977444,-93400530',
'44973116,-93410884',
'44971101,-93450400',
'45035514,-93766885',
'45035610,-93766886',
'45081631,-94286752',
'45070849,-94282026' ]
any help would be greatly appreciated. Thanks.
With nodejs you can easily write files using the fs module
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
in your case you can simply do something like
const fs = require('fs');
// I'm converting your array in a string on which every value is
// separated by a new line character
const output = arrLatLon.join("\n");
// write the output at /tmp/test
fs.writeFile("/tmp/test", output, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Let me forward you to this question for more information Writing files in Node.js

need explanation about node.js npm(express)?

please explain for me how this line work
app.get("/speak/:animal", function(req, res) {
var sounds = {
pig: "OINK",
cow: "MOO",
dog: "WOOF WOOF",
cat: "I hate humans",
goldfish: "..."
};
var animal = req.params.animal.toLowerCase();
var sound = sounds[animal];
res.send("The " + animal + " says '" + sound + "'");
});
and this line too please
app.get("/repeat/:message/:times", function(req, res) {
var message = req.params.message;
var times = Number(req.params.times);
var result = "";
for(var i = 0; i < times; i++) {
result += message + " ";
}
res.send(result);
});
The first one:
// Listens to all the get requests on the url path /speak/anything
// :animal is a placeholder, anything you pass in the url will be be available in the url param animal.
app.get("/speak/:animal", function(req, res){
// JSON object with a key value pair.
var sounds = {
pig: "OINK",
cow: "MOO",
dog: "WOOF WOOF",
cat: "I hate humans",
goldfish: "..."
};
// Converts the request parameter 'anything' in the url to a lower case string.
var animal = req.params.animal.toLowerCase();
// Tries to find the sound in the sounds object since 'anything' is no key it wont find a suitable value for the sound.
var sound = sounds[animal];
// Responds to the request with the resolved sound.
res.send("The " + animal + " says '" + sound + "'");
The second one
// Let us consider that the request /repeat/received/10
app.get("/repeat/:message/:times", function(req, res){
// the /received in the url will be available to access under the req.param.messages
var message = req.params.message;
// message = received
// Converting the times string 10 passed in the url to a number
var times = Number(req.params.times);
var result = "";
// loop will run from 0 to 9 and keep appending to the string result
for(var i = 0; i < times; i++){
result += message + " ";
}
// At the end of the for loop
// result will contain = 'received received received' 7 more time ...
// will send the response to the request.
res.send(result);
});

Node.js with Restler to return a value?

This is very early in my Node and JavaScript learning. Ideally, what I am attempting to do is create a small module querying a specific type of rest endpoint and returning a specific feature based on an attribute query. The module is correctly logging out the result, but I am struggling to get the .findById function to return this result. Although aware it has something to do with how the callbacks are working, I am not experienced enough to be able to sort it out yet. Any help, advice and direction towards explaning the solution is greatly appreciated.
// import modules
var restler = require('restler');
// utility for padding zeros so the queries work
function padZeros(number, size) {
var string = number + "";
while (string.length < size) string = "0" + string;
return string;
}
// create feature service object
var FeatureService = function (url, fields) {
// save the parameters
this.restEndpoint = url;
this.fields = fields;
var self = this;
this.findById = function (idField, value, padZeroLength) {
var options = {
query: {
where: idField + '=\'' + padZeros(value, padZeroLength) + '\'',
outFields: this.fields,
f: "pjson"
},
parsers: 'parsers.json'
};
var url = this.restEndpoint + '/query';
restler.get(url, options).on('complete', function(result){
if (result instanceof Error){
console.log('Error:', result.message);
} else {
console.log(result); // this log result works
self.feature = JSON.parse(result);
}
});
return self.feature;
};
};
var restEndpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/ArcGIS/rest/services/aw_accesses_20140712b/FeatureServer/1';
var fields = 'nameRiver,nameSection,nameSectionCommon,difficulty,diffMax';
var putins = new FeatureService(restEndpoint, fields);
var feature = putins.findById('awid_string', 1143, 8);
console.log(feature); // this log result does not
//console.log('River: ' + feature.attributes.nameRiver);
//console.log('Section: ' + feature.attributes.nameSection + ' (' + feature.attributes.nameSectionCommon + ')');
//console.log('Difficulty: ' + feature.attributes.difficulty);
So, I sorted out how to insert a callback from a previous thread. It appears it is just passed in as a variable and called with expected parameters. However, I now wonder if there is a better way to accept parameters, possibly in the form of options. Any advice in this regard?
// import modules
var restler = require('restler');
// utility for padding zeros so the queries work
function padZeros(number, size) {
var string = number + "";
while (string.length < size) string = "0" + string;
return string;
}
// create feature service object
var FeatureService = function (url, fields) {
// save the parameters
this.restEndpoint = url;
this.fields = fields;
var self = this;
// find and return single feature by a unique value
this.findById = function (idField, value, padZeroLength, callback) {
// query options for
var options = {
query: {
where: idField + '=\'' + padZeros(value, padZeroLength) + '\'',
outFields: this.fields,
f: "pjson"
},
parsers: 'parsers.json'
};
var url = this.restEndpoint + '/query';
restler.get(url, options)
.on('success', function(data, response){
var dataObj = JSON.parse(data).features[0];
console.log(dataObj);
callback(dataObj);
})
.on('fail', function(data, response){
console.log('Error:', data.message);
});
return self.feature;
};
};
var restEndpoint = 'http://services.arcgis.com/SgB3dZDkkUxpEHxu/ArcGIS/rest/services/aw_accesses_20140712b/FeatureServer/1';
var fields = 'nameRiver,nameSection,nameSectionCommon,difficulty,diffMax';
var putins = new FeatureService(restEndpoint, fields);
putins.findById('awid_string', 1143, 8, function(dataObject){
console.log('River: ' + dataObject.attributes.nameRiver);
console.log('Section: ' + dataObject.attributes.nameSection + ' (' + dataObject.attributes.nameSectionCommon + ')');
console.log('Difficulty: ' + dataObject.attributes.difficulty);
});

Categories

Resources