Mongoose using $push on an array field overwrites last entry - node.js

I am trying to create an eventlog type of field on mongodb records where I can store a list of activity. The first time I run the function, it appends to the array correctly but subsequent calls overwrite the last entry instead of appending. If I restart the server or refresh the page in the browser, it will append once again then repeat the same behavior.
I'm learning node and javascript so I'm sure it's some mistake I've made but I don't seem able to figure it out.
Javascript on the client is a tabulator event.
cellEdited:function(cell){
//cell - cell component
const oldValue = cell.cell.oldValue;
const newValue = cell.cell.value;
const title = cell.cell.column.definition.title;
var report = cell.cell.row.data;
report.event = `Updated ${title} from ${oldValue} to ${newValue}`;
$.ajax({
type: 'POST',
url: '/api/update',
data: report,
dataType: 'json'
});
}
The route that its calling on the server:
app.post('/api/update', isAuthenticated, function(req, res) {
var report = req.body;
var reason = '';
if (typeof report.event !== 'undefined') {
reason = report.event;
delete report.event;
} else {
reason = 'Report updated';
}
db.DamageReport.findOneAndUpdate({ _id: report._id}, report, function (err, doc) {
if (err) {
console.log('Err updating report ', err);
return res.send(500, { error: err});
}
/*
* Write eventlog
*/
var event = {"date": new Date(), "user": req.user.email, "event": reason };
appendLog(doc._id, event);
return res.json(doc);
});
});
The appendLog function:
function appendLog(id, entry) {
/*
* entry format:
* date: Date
* user: String
* event: String
*/
if (typeof(entry.date) !== 'object') {
entry.date = new Date();
}
db.DamageReport.findByIdAndUpdate(id, {$push: {eventLog: entry}}, function(err, result) {
if (err) {
return console.log('Error writing eventLog: ', err);
}
return(result);
});
}

It wouldn't append more than one because the previous save contained the Eventlog array in it's original form so every time it saved, it set it back to the original array and then appended the last update.

Related

Live search using autocomplete node.js and express.js

community. I am trying to implement a live search using the autocomplete library but every try is unsuccessful. I get every time a 500 server error. Every assistant is appreciated because I am new in coding.
I have a simple model for an article with title and body and I would like to show suggestions when the user search for an article
model/article.js
// Method to construct the json result set
module.exports.buildResultSet=function(docs) {
var result = [];
for(var object in docs){
result.push(docs[object]);
}
return result;
}
routes/article.js
router.get('/search', function(req, res){
encyclopediaModel.getMyArticlesByName(theRequester, function (pError, pFoundedArticles) {
if (!pError) {
// Method to construct the json result set
var result = encyclopediaModel.buildResultSet(pFoundedArticles);
res.json(result);
} else {
return res.json(JSON.stringify(pError), {
'Content-Type': 'application/json'
}, 404);
}
},req.query.title)
});
//Ajax call
$("#search-query").autocomplete({
source: function (request, response) {
$.ajax({
url: "/encyclopedia/search",
type: "GET",
data: request, // request is the value of search input
success: function (data) {
response( data );
console.log('success', data);
}
});
},
// The minimum number of characters a user must type before a search is performed.
minLength: 3,
// set an onFocus event to show the result on input field when result is focused
focus: function (event, ui) {
this.value = ui.item.label;
// Prevent other event from not being execute
event.preventDefault();
},
select: function (event, ui) {
}
});
<input id="search-query" type="text" placeholder="Articles...">
module.exports.getMyArticlesByName = function (requester, callback, pTitle){
var regex = new RegExp(pTitle["term"], 'i');
article.find({title: regex}, { 'title': 1 }).sort({"updated_at":-1}).sort({"created_at":-1}).limit(20).exec(callback);
}

SailsJs - Refresh View with new data

this is my first Node application and I am trying to refresh the view based on filters applied by users. I have a view to show data in table as below
The code for the above is
async function getAll(req, res){
try {
if (req.session.loginError == true) {
return res.redirect('/');
}
//** logic to fetch data in sData[]
return res.view('pages/list', {data:sData});
}
catch(error){
sails.log.error('Controller#getAll :: error :', error);
return res.badRequest('Cannot fetch data at this time.' + error.stack);
}
}
The above works fine. Issue is if we select some date filters like fromDate & toDate, the data from backend is fetched correctly but the view isn't refreshed.
I have put below code in ejs page to send filters to controller:
function search()
{
var searchData = {
fromDate : document.querySelector('#fromDate').value,
toDate : document.querySelector('#toDate').value,
status : document.querySelector('#status').value
};
var xmlhttp=new XMLHttpRequest();
url = "/admin/controller/filterData";
xmlhttp.open("POST",url,true);
xmlhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
xmlhttp.send(JSON.stringify(searchData))
}
Created a new method in controller named filterData as below
async function filterData(req, res) {
try {
if (req.session.loginError == true) {
return res.redirect('/');
}
var sDate = Date.parse(req.param('fromDate'));
var eDate = Date.parse(req.param('toDate'));
var sta = req.param('status')
var data= await ****.find().where({ and: [{ start_date: { '>': sDate, '<': eDate } }, { status: sta }] }).populate("***").sort('createdAt DESC');
let sData = [];
_.forEach(d, function(data){
//logic to format data
sData.push(d);
});
return res.view('pages/list', {data:sData});
}
catch (error) {
sails.log.error('Controller#getfilterData :: error : ', error);
return res.redirect('/admin/***/getAll');
}
}
The sData[] gets filtered records but the page isn't getting refreshed with new data. I am not sure if we can refresh the view like this or need to send filtered data back to function in view and then have to refresh the table from there. Please advise.
You are sending XMLHttpRequest which is an ajax call. So the page won't reload at all. It's better to return a json response from server for /admin/controller/filterData request and then populating the UI with ajax response.

Keystonejs get insterted id value

I am using updateItem method to save new record.
Following is the code example :
var vv = new vvmodel.model();
vvmodel.updateItem(vv, obj, function (error) {
if(error)
console.log('error :: ', error);
});
This is not sending any object from which we can have inserted id record. How can we get the inserted record id ?
Thanks
you should use update handler in keystoneJs
once updateHandler.process runs without error, you can access .id field on vv
var vv = new vvmodel.model({
// .... initial fields
}),
var updater = vv.getUpdateHandler(req, res, {
errorMessage: 'There was an error creating your new model:'
});
updater.process(req.body, {
flashErrors: true,
logErrors: true,
fields: 'field1, field2, field3'
}, function(err) {
if (err) {
locals.validationErrors = err.errors;
} else {
req.flash('success', 'Your model has been added');
return res.redirect('/vv/detail/' + vv.id); // here you can access the id if request was successful.
}
next();
});
see more detailed example use with sydjs site source

Getting Error Like RequestsLimitError: You just made too many request to instagram API in node js?

I am work with isntagram api in node js. i have one array and in the array store above 20k up instagram id. and then i am do foreach on that array and one by one take instagram id and go for the take bio but that time i am getting error like this RequestsLimitError: You just made too many request to instagram API. i am try every 5 call after set time out also but still i am getting same error so how can resolved this error any one know how can fix it then please let me know.
Here this is my code =>
var InstaId = ["12345687",20k more id store here in the array]
var changesessionFlage = 0;
async.each(InstaId, function (id, callback) {
async.parallel([
function (cb) {
if (id) {
setTimeout(function () {
Client.Account.getById(sess, id).then(function (bio) {
console.log("changesessionFlage" + changesessionFlage);
changesessionFlage++
//console.log("bio : ", bio._params); // here i am getting bio one by one user
if (changesessionFlage == 6) {
changesessionFlage = 0;
}
cb(null, bio._params);
})
.catch(function (err) {
console.log("get boi: ", err)
cb(null, bio._params);
})
}, (changesessionFlage == 5) ? 10000 : 0)
}
}
], function (err, results) {
if (err) {
console.log(err);
return;
}
Result = results
callback();
});
}, function (err) {
if (err) {
console.log(err);
return;
}
else {
console.log("Result=>", Result)
if (Result) {
console.log("Result[0]=>", Result[0])
var ws = XLSX.utils.json_to_sheet(Result[0]);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "People");
var wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
res.end(wbout, 'binary');
}
}
});
any one know how can fix this issue then please help me.
Your setTimeout is use incorrectly, all API calls are made at once after 10000 delay.
Since this is a one time job, just split the 20K usernames to 4K batches and execute them every hour. This way you will be under the 5k/hr API limit

Async.foreach iteration to stop forcely until first iteration executes

async.forEach(vsr.vehicles, function(vsr_vehicle, callback){
pjCustom.vehicleJson(vsr_vehicle, function(vehicleInitialize){
Vehicle.find({ where: { vehicleID: (vsr_vehicle.vehicleID).toString().trim() } }).success(function(vehicleFound){
if(vehicleFound){
//Code Logic is working fine.
}else{
vehicleBuild.save().success(function(vehicleNew){ // To create new vehicle of updated vsr
var vehicleBuild = Vehicle.build(vehicleInitialize)
pj.log("Update vehicle ............................")
temp.push(vehicleNew.vehicleID)
})
}
})
})
callback()
},function(){
res.send(204)
})
//vehicleJSON
exports.vehicleJson = function(vsr_vehicle, callback){
pjCustom.getVehicle(vsr_vehicle, function(status, vehicleId){
if (status == true) {
vsr_vehicle.vehicleID = vehicleId
callback(
{ 'vehicleID':vsr_vehicle.vehicleID).toString().trim(),'vsr_id':vsr_vehicle.vsr_id})
}
})
}
//getvehicle
exports.getVehicle = function(vsr_vehicle, callback){
if(vsr_vehicle.vehicleID !== undefined){
callback(true, vsr_vehicle.vehicleID)
}else{
Vehicle.find({ where: { 'vsr_id': vsr_vehicle.vsr_id },
attributes: ['id', 'vehicleID'],'order': 'id DESC', 'limit': '1'
}).success(function(vehicles){
var temp = (vehicles.vehicleID).split("-")
var newvehicleId = temp[0]+"-"+temp[1]+"-"+(parseInt(temp[2])+1)
callback(true, newvehicleId)
})
}
}
Explanation:
while inserting a record from vsr_vehicle. I need to check whether the vehicleID is present then it will fetch if not it will creates a new Id.
Consider this code is for updating a vehicle as well as inserting another "two" new vehicles. how to manage async process. of insertion of new vehicles.
it is not waiting for completion of first iteration and going for vehicleJson and generating same vehicleID for both new vehicles. suggest me to complete this challange.
My Code is clearly written here.
Please requesting before reading pls copy the code and paste in any JS editor you definitely will understand more than my explanation.
Your callback call in series.forEach is at the incorrect place. Here is the correction:
async.forEach(vsr.vehicles, function(vsr_vehicle, callback){
pjCustom.vehicleJson(vsr_vehicle, function(vehicleInitialize){
Vehicle.find({ where: { vehicleID: (vsr_vehicle.vehicleID).toString().trim() } }).success(function(vehicleFound){
if(vehicleFound){
callback(); // <--- call here
}else{
vehicleBuild.save().success(function(vehicleNew){ // To create new vehicle of updated vsr
var vehicleBuild = Vehicle.build(vehicleInitialize);
pj.log("Update vehicle ............................");
temp.push(vehicleNew.vehicleID);
callback(); // <--- call here
});
}
});
});
// callback(); // <--- Don't call here
},function(){
res.send(204);
});
BTW, for good practice, use semicolon (";") at the end of javascript statements

Resources