Inserting multiple entries in collection - javascript

I am attempting to create barcodes that increment by 1 for an entered quantity and add each of them to a MongoDB collection.
I use db.controlNumber.insert({controlNumber}) to do this, and I also use
console.log(controlNumber) to see my result. However, in the database, the incremented number will go to the max and enter that many times, where the console.log shows it increment.
while (i < count) {
i++;
controlNumber.controlNumber = controlVar[0] + "-" + controlVar[1] + "-" +
controlVar[2] + "-" + controlVar[3] + "-000" + i;
db.controlNumber.insert(controlNumber);
console.log(controlNumber);
}
I expect my mongoDB collection to have control number (for example if user wants 5 control numbers)
a-b-c-d-001
a-b-c-d-002
...
a-b-c-d-005
Instead, it makes 5 entries of
a-b-c-d-005

You're mutating controlNumber.controlNumber. Instead, create a new object to insert:
const toInsert = Object.assign({}, controlNumber, { controlNumber: i });
db.controlNumber.insert(toInsert)
It'd likely also be worth either using async/await or promises to handle asynchronous calls. If you do await db.controlNumber.insert(controlNumber) you wouldn't have run into any problems because it would have waited for the document to be fully inserted before moving on to the next one.

Related

Better way to do this with Node.js, Express, and MySQL?

So I was wondering if anyone had a better method for my problem. Basically I want a record inside a record that I'm inserting into a database. What I mean is, I need to have a history of all the changes made to the record when updated. So whenever the record is updated, I save the info in a "Updates" column. Every time theres an update, I select the updates from that record, concatenate the new info onto the old updates and inserting it. See my code below.
app.post("/updateRecord", function(req,res){
var prevResultUpdates = "";
async function first(){
con.query("SELECT * FROM Equipment WHERE Serial="+req.body.serial+" AND Part="+req.body.part, function(err,result,fields){
if (err) throw err;
console.log(result[0]['Updates'])
return prevResultUpdates= prevResultUpdates + "," + result[0]['Updates']
});
}
async function second(){
await first();
var customer = req.body.customer;
var update = "\'" + prevResultUpdates + ',' + req.body.update + "," + Number(Date.now()) + "," + req.body.customer + ',' +"\'";
var serial = req.body.serial;
var part = req.body.part;
var sql="Update `Equipment` SET `Customer`= '"+customer+"', `Updates`="+update+" WHERE Serial=" + serial + " AND Part=" + part;
con.query(sql,function(err,result,fields){
if (err) throw err;
res.json(result)
})
}
second();
res.end()
})
Any thoughts on how to do this better?
A bunch of suggestions here.
First, put a column in your table like this:
last_change TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
It will always contain the time of the most recent INSERT or UPDATE operation on each row, automatically without you needing to mention it in your SQL.
Second, be aware that
UPDATE Equipment SET Updates = Updates + ' some text string'
works. You can change a column in place, without fetching its former value. But, this can fail when the column gets too long. So, do this instead.
UPDATE Equipment SET Updates = RIGHT(Updates + ' some text string', 255)
assuming your Updates column is defined as VARCHAR(255). I used RIGHT() rather than LEFT() because presumably the most recent update is the most interesting.
Third, you'd probably be wise to normalize this, to add an Equipment_history table. Instead of appending your update log to a column, insert a new row into Equipment_history. That table might have these columns
equipment_history_id INT primary key
equipment_id INT foreign key to Equipment table
customer VARCHAR(255) identity of the customer
update VARCHAR(255) reason for update
last_change TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
This lets you reconstruct the history of your updates if need be.

How to I use my firebase variables as an integer?

I have a simple program that you can post/accept games then report back the score. I am having an issue of updating the score as information stored in firebase is stored as a string. How do I take my score as an integer to add to it?
if (selfScore > oppScore) {
var ref = new Firebase('taken out');
var selfRef = firebase.database().ref("users/" + (selfKey));
selfRef.update({
"tScore": ("tScore" + 3)
});
}
Ideally, the score would take the previous score and add 3 but this is not the case. I'm new to firebase so if this is obvious, my bad. An edit to clarify when I remove tscore and just have tScore: +3 it just changes tScore to 3, it doesn't add it.
You cannot make some operations on field value within the update() method. So you should first read the value from the database and then update the record with the new value.
The best approach is to use a transaction for such operation, which will automatically do the read/write operation and, in addition, ensure "there are no conflicts with other clients writing to the same location at the same time".
You would then do as follows:
var selfRef = firebase.database().ref("users/" + selfKey + "/tScore");
selfRef.transaction(function(currentValue) {
return currentValue + 3;
});

How can I stop a connection from closing early?

I am trying to move a large amount of data from a mysql database (an amount larger than the max query size) and will need to run it through a loop in chunks to do so. The issue I am having is that even in the small sample size of 50 records, I am consistently missing about half of them as it seems the connection is being closed before the loops have finished. The code snippet I am having trouble with is below:
for(var j = 0; j < maxNum; j+=increment){
// populates the array that can be used to find the mods that have been purchased
console.log("START = " + j + " END = " + (j+increment));
con.query("SELECT * FROM sometable WHERE id BETWEEN " + j
+ " AND " + (j + increment), function(err, rows, fields){
if(!err){
console.log("ROWS = " + rows.length);
for(var a = 0; a < rows.length; a++){
arrayOfObjs.push(rows[a]);
console.log(rows[a].ID);
// If the inner loop is at the end and the while loop is about to end this cycle
if( (a + 1 == rows.length) && ((userCounter + increment - 1) > maxNum)) {
// Loop through all the user objects and if it has records, add it to that item
for(var b = 0; b < arrayOfUsers.length; b++){
arrayOfUsers[b].objs = returnObjById(b, arrayOfMods);
// If the loop is ending
if(b+1 == arrayOfUsers.length){
done1 = true;
// temp force close
shutDown()
}
}
}
}
}
else{
console.log(err);
}
})
}
The maxNum is supposed to represent the total number of users in the table as a whole, and the increment would be the size of the chunks. The returnObjs function does not call anything and is a simple switch that has no effect on the functionality. The shutDown function is a mysql connection end with a process.exit for a callback. That function is what is ending the script before it is finished but as I am new to Node, I do not know how I could adjust this in order to ensure that this does not continue to happen. Any suggestions would be appreciated as this is being done partly as a way to learn Node since it wouldn't be difficult to do in a language I'm familiar with.
I see two possible problems here.
First, conn.query() is probably an async function (by looking at the callback function I see there). That means node won't wait for the callback to be called before continuing execution, resulting in your first loop iterations being executed all before even the first conn.query() callback is called.
I suggest you have a look at this excellent library : async. It helps a lot with async operations, like in your case when you want to wait for the callback before starting another iteration. For that matter, the async.series() function may be helpful.
Secondly, you call to shutdown() seems to automatically happen when the last iteration of the third for loop has finished, but you are still in the first iteration of your first and second for loops. This means j will never be incremented, nor will a. The shutdown() function should be called at the end of the last iteration of your first for loop.
EDIT: I overlooked your if before the third for loop. I'm not sure what the purpose of the (userCounter + increment - 1) > maxNum check is, but if it prevents the third loop from being called when a or j are not at their max value, then you can discard my second point. The async problem is still there though, and is most likely the cause of your problem.

getJSON on Sharepoint list stops at 1000

$.getJSON("urlhere", {}, function(data)
{
// Other code is commented out, I'm just using the following loop to test.
for(var a = 0; a < 2546; a++)
if(a > 995)
alert((a + 1) + ": " + data.d.results[a].Column2);
});
For some reason, I wasn't getting all the things from my list that I needed. So I put in this loop to test it and it stops at 1000 for some reason. Why does this happen and how do I fix it?
SharePoint only returns 1000 results per "page." If you look, there should be a "link" element in there near the bottom of the JSON that contains a link to the next 1000 results.
That's how it is when it returns XML, anyway. Haven't tried JSON, but I'm sure it's similar.
'urlForListData' + '?$filter=Building eq \'' + building + '\''
I found out that you can filter the list for what you need so that it never exceeds 1000, which was much simpler than what I was doing before. Of course, Building is a column in the SharePoint list and building is a variable holding the requested building number.

losing global variable value

This is for a gameing application
I declare the variable skipnpc which is designed as an indicator that a non player character has used his turn and any AI code related to his behavior is skipped for a period of time. the problem I have is I am loosing the value of skipnpc somehow I indicated where in the console.log commands I issue is related to varaible scope but I don't understand how to fix it.
function npcMovement() {
skipnpc = false;...
sql4 = "SELECT id FROM game_moblist WHERE spawn_id =" + spawnid + " AND posx=" + parseInt(mobpathx[mobpathx.length - 1]) + " AND posy=" + parseInt(mobpathy[mobpathy.length - 1])
connection.query(sql4, function (err, send, fields) {
console.log("skipnpc pathing")
io.sockets.emit('groupmoveresult', send, parseInt(mobpathx[mobpathx.length - 1]), parseInt(mobpathy[mobpathy.length - 1]))
skipnpc = true
console.log("skipnpc=true:" + skipnpc)
});
console.log("skipnpc = false:" + skipnpc)
Later I use
if (skipnpc==false){
...
before any further AI code is attempted
connection.query is executed asynchronous. Thus you get to your final line here before it is done.
To put it real simply, skipnpc is guaranteed to still be false by the time you hit your last console.log(...). You're not giving your connection.query(...) any time to execute before trying to look at its result. Anything that relies on the result of connection.query(...) has to be executed as part of the callback you passed to it; otherwise none of the results will have come in when you try to access them.
Asynchronous programming takes some getting used to. You might be able to reorganize your code using the async module and using its waterfall(...) method so everything doesn't wind up deeply nested. But you've got to realize that if you make an asynchronous call, your code will flow right past it.

Categories

Resources