NodeJS MySQL DATE() returns undefined - javascript

I'm trying to get Node to query my database and send the results to the client where it is placed into a <table>, but with the timestamp removed from the date.
I have the following bit of Node querying my database:
pool.query(
"SELECT DATE(completed), duration, submitted FROM workentries WHERE iin = ?",[iin],
function(error, results) {
if(error) throw error;
connection.release()
res.send(results);
}
)
The client-side JS:
const httpr = new XMLHttpRequest();
httpr.onload = () => {
let responsej = JSON.parse(httpr.response)
for(i in responsej) {
document.getElementById("workentry-table").innerHTML += "<tr><td>"+responsej[i].completed+"</td><td>"+responsej[i].duration+"</td><td>"+responsej[i].submitted+"</td></tr>";
}
}
httpr.open('GET', '/workentry-list');
httpr.send();
This is the result:
This is how the dates are formatted in the database:
I'm also going to want to reformat the timestamp on the submitted datetime, so it'd be a big help if I can find out how to properly format date/time for this case.
(I'm sorry if this is obvious, but I'm relatively new to Node. I Googled like a madman but couldn't find a solution, which either means this is an uncommon issue or I'm doing something stupid)
EDIT:
Fixed undefined by using DATE(completed) AS completed to the query
Fixed the date/time format by using toLocaleString() in the client-side

You need to give an alias to the column in the SELECT list so you can refer to it as responsej[i].completed. Otherwise, you need to use responsej[i]['DATE(completed)']
And to format it as you want, use the DATE_FORMAT() function rather than returning a DATE.
SELECT DATE_FORMAT(completed, '%Y-%m-%d') AS completed, duration, submitted FROM workentries WHERE iin = ?

Related

How to (quickly) download huge amounts of data in Firebase?

I'm sending data to the Firestore at 33Hz. This means that over time, a lot of data is stored.
I need to be able to download this data. For that, I have made a Http Function in firebase, that receives the user uid, device's serial number, start date/time and end date/time. The function then tests if the user exists and also if he does have that serial number. Then it queries firestore and append data to a JSON object, that eventually is send as a response.
But, depending on how long the query has been made, the function will timeout. It does work for short periods.
How should I do to make the function faster? Am I using the wrong tool?
[...]
const nD1 = db.collection('grind-bit').doc(req.query.serial).collection('history').where('date', '>=', startdate).where('date', '<=', enddate).get().then(snapshot => {
snapshot.forEach(doc => {
elem = {};
elem.date = doc.data().date;
elem.rms0 = doc.data().rms0;
elem.rms1 = doc.data().rms1;
elem.rms2 = doc.data().rms2;
data[key].push(elem);
});
if(data[key].length) {
let csv = json2csv(data[key]);
csv = JSON.stringify(csv);
res.set("Content-Type", "text/csv");
return promises.push(res.status(200).send(csv));
} else {
return promises.push(res.status(401).send('No data has been found in this interval.'));
}
[...]
If the timeout is caused by the fact that you're trying to read/return too much data in one go, you might want to consider limiting how much data you return. By adding a limit() clause to your query, you can limit how much data it returns at most.
const nD1 = db.collection('grind-bit').doc(req.query.serial).collection('history')
.where('date', '>=', startdate).where('date', '<=', enddate)
.limit(100)
.get().then(snapshot => {
snapshot.forEach(doc => {
...
This of course means that you may have to call the HTTP function multiple times to ensure you process all data. The simplest approach for that is: if you get 100 results (or whatever limit your specify), try another time after processing them.
Also see:
The Firebase documentation on limiting query results

How to properly use ON DUPLICATE KEY UPDATE in Node.js MySQL

I'm using Node.js to push values to a MySQL table like:
for (var i = 0; i < data.length; i++) {
flattenedData.push([data[i].id, data[i].adult, data[i].backdrop_path, JSON.stringify(data[i].genre_ids), data[i].original_language, data[i].original_title, data[i].overview, data[i].popularity, data[i].poster_path, data[i].release_date, data[i].title, data[i].video, data[i].vote_average, data[i].vote_count]);
//console.log(flattenedData);
}
db.query("INSERT INTO movies (id, adult, backdrop_path, genre_ids, original_language, original_title, overview, popularity, poster_path, release_date, title, video, vote_average, vote_count ) values ?", [flattenedData], function (err, result) {
if (err) {
throw err;
}
else {
console.log('data inserted' + result);
}
});
I want to add ON DUPLICATE KEY UPDATE to the query, but I keep getting syntax errors, can anyone show me the proper way?
I'm going to short this to three columns, and assume id is the only unique column.
db.query("INSERT INTO movies (id, adult, backdrop_path) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE adult=VALUES(adult), backdrop_path=VALUES(backdrop_path)",
flattenedData, function (err, result) {
...
This means if the insert results in a duplicate on the primary/unique column (id), then copy the other columns from the values you tried to insert in the VALUES clause into their respective column, overriding what their value was previously in the existing row.
There's no shortcut for that; you have to spell out all such column assignments.
I'm pretty sure the argument to query() for parameters should be an array, but it looks like your flattenedData is already an array since you're pushing to it. So I don't think you need to put it in square-brackets.
I was confused by how to get this to work in a react/redux app and eventually came to the "correct" method.
My implementation required me to update one field value per record for an arbitrary number of records in a table with 21 fields.
If you are passing data as an array structure it like [['dataString',666.66],['dataString2',666666.66],['dataString3',666666666.66]] and then make sure you pass this whole thing as an array to the query function. See itemQtyData in my code sample below.
Another thing that tripped me up was the use of brackets around the values replacement string. I didn't need them. The examples I looked at showed implementations that needed them. I also only used a single ? for all the values. So instead of using (?,?) to represent the values in the query, which didn't work, I used ?.
I found it unnecessary to supply all the field names and the corresponding values for the table. MySQL will warn you if fields don't have a default value. I haven't found this to be an issue in this case.
You can console.log the formatted sql in SqlString.format function in the file node_modules/sqlstring/lib/SqlString.js. I found this useful to see exactly why the query wasn't working and to have something that I could plug into MySQL Workbench to mess around with.
Edit: You can also do this console.log(connection.query(yourQuery, [someData], callback)) and you get the sql and lot's more when the function executes. Might make more sense than adding console.log calls to the module code.
Hope this helps!
let itemQtyData = order.map(item => {
return [
`${item.id}`,
`${Number(item.products_quantity - Number(item.quantity_to_add))}`
];
});
const updateQtyQuery =`INSERT INTO products (products_id, products_quantity) VALUES ? ON DUPLICATE KEY UPDATE products_quantity=VALUES(products_quantity)`;
connectionOSC.query(
updateQtyQuery,
[itemQtyData],
(error, results, fields) => {
if (error) throw error;
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: saleId,
response: results,
isBase64Encoded: false
};
context.succeed(response);
});

How to get all records from collection using createddate field in meteor js application

I have a sample transactions collection similar to below
[
{"_id":"123","createddate":"2017-07-24T09:43:31.028Z"},
{"_id":"124","createddate":"2017-07-25T09:43:31.028Z"},
{"_id":"125","createddate":"2017-07-26T09:43:31.028Z"},
{"_id":"123","createddate":"2017-07-28T09:43:31.028Z"},
{"_id":"126","createddate":"2017-07-27T09:43:31.028Z"}
]
But in my production we have around 50-60 records for each date(createddata field).I need to get all the records for a particular date based on selection then download that.
I used below:
Meteor.methods({
gettransactionsdata:function(){
let transactionRecord = transactions.find({"createddate":"2017-07-26"});
return transactionRecord;
}
});
When I try calling above function it is returning transactionRecord as undefined. How can we do this?
You're storing dates as strings instead of dates which is not recommended for numerous reasons. For a simple day you can do a $regex search to find the strings that begin with the day you're looking for:
transactions.find({ createddate: { $regex: /^2017-07-26/ }});
You could also just pass that date string to your method for a bit more flexibility:
Meteor.methods({
gettransactionsdata(dateStr) {
return transactions.find({ createddate: { $regex: new RegExp('^'+dateStr) }});
}
});

Firebase push() method shuffle the list data

Have created a chat application and we use firebase for realtime communication.
Sometimes i noticed that push() method shuffle the list data. We can see in the below image :
If we see in above image i am just trying to communicate with someone i said hello in reply user said hey, again i said i need some help then user said That's what I'm here for. What can I assist you with? in the reply but if we see in the image users reply is appearing first.
It happens intermittently that's why i didn't figure out this problem. So please someone help me out what shall i doing wrong.
var pushMessageToFB = function(){
var chatMsgRef = db.child("chatMessages").child("gr1").child("ch_usr1_usr2");
var message = {
type: "chat",
content: data.messageText,
timestamp: Date.now(),
by: user.id
};
chatMsgRef.push(message, function(err){
if (err){
console.log('error occurred while pushing message to fb : err ' + JSON.stringify(err));
}
});};
var loadChatMessages = function(){
var chatMsgRef = db.child('chatMessages').child("gr1").child("ch_usr1_usr2");
$scope.chatMessages = chatMsgRef.orderByKey().limitToLast(50);
};
Don't use Date for remote data. It will be slightly offset on every machine. Use ServerValue.TIMESTAMP which Firebase will convert to the server's Unix epoch time when the data is written. This ensures consistency of order across clients.
You didn't provide any code for how you're reading or displaying the chat messages, but since you're trying to show them in chronological order I assume your query uses orderBy("timestamp"). If you use ServerValue.TIMESTAMP when you write the message it will be guaranteed to sort in the order that it was written to the database.

Add Query conditionals to related object's properties in parse.com with JS SDK

It is possible to sort and use conditionals to a related object in parse.com?
I have Users which have a pointer to profilePictures. I would like a query such as:
var query = new Parse.Query(Parse.User);
// include images
query.include("profilePicture");
// get only regular users
query.notEqualTo("isAdmin", true);
// who has uploaded an image
query.exists("profilePicture");
// and such image was updated in the last month
query.lessThanOrEqualTo("profilePicture.updatedAt", today);
query.greaterThanOrEqualTo("profilePicture.updatedAt", lastMonth);
// and order the resultset by profilePicture.updatedAt
query.ascending("profilePicture.updatedAt");
Unfortunatelly this returns a 105 error from parse.com as it can't find the property...
{"code":105,"error":"profilePicture.updatedAt is not a valid order key"}
All the posts I find are quite old (~2012) and maybe something changed lately. Any idea on how to achieve this?
For sorting I don't really care. I've alrady implemented a comparator, but I need to filter by date as I can't query for 1000's of profiles for nothing
You cannot achieve that with include and dot-notation. You better use inner queries for this:
var innerQuery = new Parse.Query("PICTURES"); // query on your profile picture class
innerQuery.lessThanOrEqualTo("updatedAt", today);
innerQuery.greaterThanOrEqualTo("updatedAt", lastMonth);
var query = new Parse.Query(Parse.User);
query.matchesQuery("profilePicture", innerQuery); // users that match the picture criteria
query.find({
success: function(users) {
// You get selected users with the profilePicture criteria
}
});

Categories