I am trying to solve an issue where I am trying to write a json file with user input details. But each time I input new details it is overwriting the existing data.
How can I avoid overwriting existing json object in a json file and add new object in the array instead based on user input ?
userData.json:
[
{
"name": "Name",
"number": "4334343",
"email": "email#email.com",
"message": "sdsd"
}
]
server.js :-
app.get("/myaction", function (request, response){
var name = request.query.name;
var number = request.query.number;
var email = request.query.email;
var message = request.query.message;
if (name != "") {
response.send("Your name is " + name + "number"+ number + "email"+ email + "message" + message);
const sendData = [{
name:name,
number:number,
email:email,
message:message
}];
fs.stat('./userdata.json', function(err, stat) {
if(err == null) {
console.log('File exists');
} else if(err.code === 'ENOENT') {
// file does not exist
var data = JSON.stringify(sendData,null, 2);
fs.writeFile('./userdata.json', data, (err) => {
if (!err) {
console.log('done');
}
});
} else {
console.log('Some other error: ', err.code);
}
});
} else {
response.send("Please provide info");
}
});
In order to append data instead of replacing it you can pass a+ flag to fs.writeFile:
fs.writeFile('./userdata.json', data, { flag: 'a+' }, (err) => {
if (!err) {
console.log('done');
}
});
It will create the file if the file does not exist. If the file exists, then the content will be appended.
Here is the dirty way to do it:
fs.readFile('./userdata.json', (err, data) => {
if (err){
console.log(err);
} else {
obj = JSON.parse(data);
obj.push(sendData);
json = JSON.stringify(obj);
fs.writeFile('./userdata.json', json, callback);
}});
Everytime you want to add a record, read the array, append to it and dump it again. However, consider switching to a database to avoid this.
Related
I have recently been desgining a back end web server that is primarily used to manipulate data from a mysql database. The server is designed in a DOM format, with a controller folder and an app.js
I have implemented a few GET, POST PUT requests in such a format
This is what one GET request looks like
app.get("/movies/:movieID/", (req, res, next) => {
const movieID = parseInt(req.params.movieID);
// if userID is not a number, send a 400.
if (isNaN(movieID)) {
res.status(400).send();
console.log("Error has occured with getting movieID")
return;
}
movies.findByID(movieID, (error, movie) => {
if (error) {
res.status(500).send();
console.log("get Id has error")
return;
};
if (movie === null) {
res.status(404).send();
console.log("movie ID is invalid")
return;
};
//console.log(movie)
res.status(200).send(movie);
console.log("Successful movie ID")
});
});
This is inside the controller folder
,findByID: function (movieID, callback) {
var dbConn = db.getConnection();
const findMovieByIDQuery = "select * from movies left join genres on movies.genreid = genres.genreid left join reviews on reviews.movieid = movies.movieid where movies.movieid = ?;";
dbConn.connect(function (err) {
if (err) {
console.log(err);
return callback(err, null);
} else {
dbConn.query(findMovieByIDQuery, [movieID], (error, results) => {
dbConn.end();
if(error) {
return callback(error, null);
}
else if (results.length === 0) {
callback(null, null);
return;
};
console.log(results)
return callback(null, results[0]);
});
}
});
}
How ive implemented it is to take the users input, in this case a number and input it in the query based on the ? position.
However, I am now trying to create on whereby the user is able to search based on a string not just an ID number.
This is my code so far
app.get("/movies/:movieKeyword", (req, res, next) => {
console.log("Reached the app.js")
movies.findByKeyword((error, moviesAvailable) => {
if (error) {
console.log(error);
res.status(500).send();
};
res.status(200).send(moviesAvailable);
});
});
,findByKeyword: function(callback) {
console.log("Reached find by keyword")
var dbConn = db.getConnection();
const findAllMoviesQuery = "SELECT title, description, cast, time, opening_date, picture from movies WHERE title LIKE '% ? %';"
dbConn.connect(function (err){
dbConn.query(findAllMoviesQuery, (error, results) => {
if (error) {
return callback(error, null);
};
console.log(results)
return callback(null, results);
});
});
}
To use the LIKE query in mysql, I need the variable to be stored in this format: "% ? %"
However, I am not able to get this query to work as the program is not able to insert the variable into the ? this time as it is within 2 quotation marks and 2 percentage symbols
I think you can use Template Literals. Here is a resource, Template Literals. You can remove the percentage signs and replace them with this syntax ${variable_name}
Below is the piece of code i have written , to get the result but null in response
I am using selectObjectContent api to get the results with the simple SQL query
const bucket = 'myBucketname'
const key = 'file.json.gz'
const query = "SELECT * FROM s3object "
const params = {
Bucket: bucket,
Key: key,
ExpressionType: "SQL",
Expression: query,
InputSerialization: {
CompressionType: "GZIP",
JSON: {
Type: "LINES"
},
},
OutputSerialization: {
JSON: {
RecordDelimiter: ","
}
}
}
s3.selectObjectContent(params,(err, data) => {
if (err) {
console.log(data)
} else {
console.log(err)
}
})
I have found the solution to it. was logging error when getting successfull result/data , so corrected it below. Also i have found the way to read stream buffer data
s3.selectObjectContent(params,(err, data) => {
if (err) {
console.log(err)
} else {
console.log(data)
}
})
const eventStream = data.Payload;
// Read events as they are available
eventStream.on('data', (event) => {
if (event.Records) {
// event.Records.Payload is a buffer containing
// a single record, partial records, or multiple records
var records = event.Records.Payload.toString();
console.log( records )
} else if (event.Stats) {
console.log(`Processed ${event.Stats.Details.BytesProcessed} bytes`);
} else if (event.End) {
console.log('SelectObjectContent completed');
}
I have a bot. It can input some text and return some word.
I would like to use MongoDB. Because Heroku can't store data.
So I add function.js that use mongoose.
console.log('data.functionswitch = ' + data.functionswitch);
console log is work fine. It can reply what i want.
return data.functionswitch;
but return data.functionswitch only return undefined when i call it in input.js/.
I have try async/await.
But it only stops working.
How can I improve it and make it work? Thank you.
-
-
2018/03/15 updated
function.js
function switchfind(id, name, callback) {
mongodb.functionSwitch.findOne({
groupid: id, functionname: name
}, function (err, data) {
if (err) {
console.log(err);
callback(null);
return;
}
else if (!data) {
console.log("No record found")
callback(null);
return;
}
console.log('date = ' + data);
console.log('data.functionswitch = ' + data.functionswitch);
callback(data.functionswitch);
return;
})
};
input.js
function parseInput(rplyToken, inputStr) {
//console.log('InputStr: ' + inputStr);
_isNaN = function (obj) {
return isNaN(parseInt(obj));
}
let msgSplitor = (/\S+/ig);
let mainMsg = inputStr.match(msgSplitor);
let trigger = mainMsg[0].toString().toLowerCase();
exports.mongoose.switchfind(mainMsg[1], mainMsg[2], function (functionswitch) {
console.log('functionswitch = ' + functionswitch)
if (functionswitch === null) {
console.log('HERE === NULL ')
}
if (functionswitch == 0) {
console.log('HERE != 0')
return;
}
else if (functionswitch != 0 ) {
console.log('HERE != 0')
if (inputStr.match(/\w/) != null && inputStr.toLowerCase().match(/\d+d+\d/) != null) return exports.rollbase.nomalDiceRoller(inputStr, mainMsg[0], mainMsg[1], mainMsg[2]);
}
})
}
update
const mongoose = require('mongoose');
let uristring = process.env.mongoURL ||
'mongodb://XXXXXXX';
mongoose.connect(uristring);
mongoose.connect(uristring, function (err, res) {
if (err) {
console.log('ERROR connecting to: ' + uristring + '. ' + err);
} else {
console.log('Succeeded connected to: ' + uristring);
// console.log('allswitch: ' + allswitch);
}
});
var functionSchema = new mongoose.Schema({
groupid: String,
functionname: String,
functionswitch: String
});
// Compiles the schema into a model, opening (or creating, if
// nonexistent) the 'PowerUsers' collection in the MongoDB database
var functionSwitch = mongoose.model('functionSwitchs', functionSchema);
The problem in your code is that you are using findOne as it was synchronous. You cannot simply return the data, you have to use a callback.
Here is a tutorial about callbacks.
Example of what it should look like :
// The find function
function switchfind(id, name, callback) {
mongodb.functionSwitch.findOne({
groupid: id,
functionname: name
}, function (err, data) {
// Handle error
if (err) {
callback(null);
return;
}
// Handle empty data
if (data == null) {
callback(null);
return;
}
// Handle with data
callback(data.functionswitch);
})
};
// How to call it
funcX() {
switchfind(id, name, function (functionswitch) {
if (functionswitch === null) {
// Handle the error
}
// Handle the data
});
}
I have to insert multiple different JSON objects in MongoDB and then check whether the some of the data already exist in the database and run another query based on whether the data exists or not for each JSON Object. How can I do in expressjs? I am using mongojs package for working with MongoDB. The code I typed is below:
app.post('/addcard/:id', function(req, res) {
console.log("Received Add Card Request");
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
var yrval = req.body.yrval;
var monval = req.body.monval;
var dateval = req.body.dateval;
for (var i=0;i<req.body.phone.length;i++){
//console.log(i);
var card = new Card({
cardType : req.body.cardtype,
cardTitle : req.body.cardtitle,
allowMultipleStore : false,
phoneNumber : req.body.phone[i],
messageUser : req.body.message,
expiryDate : new Date(year+yrval,month+monval,day+dateval),
creditPoints : req.body.creditpoints,
punchCount : req.body.punch,
messageReachPunchLimit : req.body.limitmessage,
merchantUsersId : mongoose.Types.ObjectId(req.body.merchantuserid),
merchantId : mongoose.Types.ObjectId(req.params.id)
});
console.log(card);
db.carddata.insert(card, function (err,docInserted){
// console.log(card);
console.log(i);
if (err) throw err;
db.userdata.find({phoneNumber:req.body.phone},function (err,docs){
console.log("hiss");
if (err) throw err;
if (docs.length!=0){
var carduser = new CardUsersAssignment({
cardId : docInserted._id,
userId : docs[0]._id,
remainingCreditPoints : req.body.creditpoints,
remainingPunchCount : req.body.punch
});
db.carduser.insert(carduser,function (err){
console.log(" Card Details saved successfully_existing");
//console.log(i);
})
}//If (docs.length!=0)
else{
console.log(" Card Details saved successfully");
}
})//Finding by PhoneNumber
console.log(i+1);
})//Insert Function
console.log("hi");
} // End of For Loop
res.json({
success:true,
message:"Hello. You did it!"
});
});
This code is written as if I were writing for sequential execution. I know that NodeJS is asynchronous. I tried async.waterfall but it is giving error with the mongodb query function. Any help would be great. I am a NodeJS noob. Links to article which discuss similar scenarios would also be great.
You can achieve this using async library.
There is two way to do it.
Use async each to iterate your data and inside each check data is first check data is already exist or not, based on find result you can return or insert the doc.
It is the same as 1st, the only different is you just can to use waterfall for find and insert.
First Approach:
async.each(req.body.phone, function(data, callback) {
// Create card Info
db.carddata.insert(card, function (err,docInserted){
if (err) {throw err;}
db.userdata.find({phoneNumber:req.body.phone},function (err,docs){
if (err) {throw err;
} else if ( docs.length ){
// create carduser data
db.carduser.insert(carduser,function (err){
if (err) {throw err;}
callback();
}
} else {
console.log(" Card Details saved successfully");
callback();
}
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
Second Approach:
async.each(req.body.phone, function(data, callback) {
//create card data
let data = {}
data.phone = req.body.phone;
data.docInserted = data.docInserted;
data.cardata = cardData;
async.waterfall([
insertCard,
updateDataFind,
cardDataInsert,
async.apply('insertCard', data)
], function (err, result) {
if(err){
if(err.success){
callback();
}
throw err;
}
callback();
});
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
function insertCard(data, callback){
db.carddata.insert(card, function (err,data.docInserted){
if(err){throw err;}
callback(null, data);
}
}
function updateDataFind(data, callback){
db.userdata.find({phoneNumber:data.phone},function (err,docs){
if (err) {throw err;}
else if (docs.length!=0){ callback(null, data); }
else { callback({success:true}) }
}
}
function cardDataInsert(data, callback){
// create card user or pass from data.
db.carduser.insert(carduser,function (err){
if (err) {throw err;}
callback(null, data);
}
}
I am trying to insert the bulk data into the collection. Inserting into the collection is happening properly. but i want the return callback from the Oninsert function. Can anybody help me to return the callback.here is my code.
var Invitation = require('../models/invitation');
var uniqueinvitations=[ { email: 'tyu#gmail.com', role: 'Developer' },
{ email: 'rty#mailinator.com', role: 'Developer' } ]
Invitation.collection.insert(uniqueinvitations, onInsert);
function onInsert(err, docs) {
if (err) {
console.log("Error while inserting the data into the Invitation");
} else {
//i want to return the Callback here,
var invitations = _.map(docs, '_id');
}
}
Something like this should work and display id or inserted rows
function onInsert(err, docs) {
if (err) {
console.log("Error while inserting the data into the Invitation");
} else {
var invitations = docs.map(x => x.id);
console.log("inserted : " + invitations);
}
}