How to delay/wait for JSON modification using NodeJS? - javascript

I am getting keywords (ExpressJS):
/*
* GET keywords.
*/
router.get('/keywords', function(req, res) {
// Check if user is logged in
if (req.user) {
var db = req.db;
var user = req.user;
db.collection('users').findOne({_id: user._id},
function(err, result) {
// console.log(result.keywords.RFD);
res.json(result.keywords.RFD);
});
}
});
I am updating my MongoDB (ExpressJS/Mongoose):
/*
* POST keyword.
*/
router.post('/addkeyword', function(req, res) {
// Check if logged in
if (req.user) {
var db = req.db;
var user = req.user;
var keywords = validator.stripLow(validator.trim(req.body.keywords));
db.collection('users').update({_id: user._id}, {'$addToSet': { 'keywords.RFD' : keywords } }, function(err, result) {
if (err) throw err;
if (!err) {
console.log('Keyword added: ' + keywords);
};
});
}
});
The addKeyWord function (JS):
function addKeyword(event) {
event.preventDefault();
// Super basic validation - check if empty
var errorCount = 0;
var keywordRead = $('#addKeyword input#inputKeyword').val();
if($('#addKeyword input').val() === '') {
keywordAlert = '<div class="alert alert-danger">Please fill in a keyword.</div>'
$('#alert').html(keywordAlert);
return false;
}
else {
// If it is valid, compile all user info into one object
var newKeyword= {
'keywords': keywordRead,
}
// Use AJAX to post the object to our adduser service
$.ajax({
type: 'POST',
data: newKeyword,
url: '/api/addkeyword',
dataType: 'JSON',
success: populateKeywords(true)
});
}
};
I am populating the page (JavaScript/jQuery):
var keywordContent = '';
$.getJSON( '/api/keywords', function( data ) {
// For each item in our JSON, add a table row and cells to the content string
$.each(data.reverse(), function(){
keywordContent += '<div class="form-group">';
keywordContent += '<span class="label label-success">' + this + '</span>';
keywordContent += ' x';
keywordContent += '</div>';
}).reverse();
// Inject the whole content string into our existing HTML table
$('#myKeywords').html(keywordContent);
});
The problem is that when I add a keyword, the keywords re-populate, and sometimes the jQuery is too fast and does not list the new keyword.
I would like to add some loading/checking to see if the JSON has changed? The population is only accurate if the /addkeyword is fast enough.

If i understood correctly, you want to populate page only after new keyword addition is complete. As node works on single thread model these issues are likely to occur. No problem with node its just non-blocking way of node. For this kind of stuff i would highly suggest looking at async package of node.
You might have to use something like ,
async.series([
function(){ ... },
function(){ ... }
]);

/*
* POST to addkeyword.
*/
router.post('/addkeyword', function(req, res) {
// Check if logged in
if (req.user) {
var db = req.db;
var user = req.user;
var keywords = validator.stripLow(validator.trim(req.body.keywords));
db.collection('users').update({_id: user._id}, {'$addToSet': { 'keywords.RFD' : keywords } },
function(err, result) {
if (err) throw err;
if (!err) {
console.log('Keyword added: ' + keywords );
// the one line I needed is below:
res.end('{"success" : "Updated Successfully", "status" : 200}');
};
});
}
});
I've commented above the one line that was missing and that was needed!

Related

How to send an ID to the database for searching in callback function

I have a code snippet in db.js as below,
exports.asyncGetAllData = function (cb) {
connection.connect(function(err) {
connection.query("SELECT * FROM prices WHERE=" + "'" + ID + "'", function (err, result) {
//console.log("info:" + cb);
if (err) console.log("Error: " + err);
else
{
cb(result);
}
});
});
};
I want to pass and ID from app.js into asyncGetAllData function in db.js. The following code snippet is in app.js
app.get('/test/getPriceTrend/:parameter', function(req, res) {
console.log('SERVER::testGetPriceTrend');
console.log(req.url);
var str=req.url;
db_connection.asyncGetAllData(function(data) {
var obj = str.split("&");
var ID = obj[0].split("/")[3];
console.log(JSON.stringify(data));
res.setHeader('Accept', 'application/json');
res.writeHead(res.statusCode);
//The following piece of code will send information from the database
res.write("hello");
res.end();
});
});
In the above-mentioned code (app.js), I have parsed ID from a get request. I want to send this ID to asyncGetAllData function which resides in db.js. How can I send ID parameter and fetch the result?
Thanks in advance,
You can just extend the function with an additional argument
exports.asyncGetAllData = function (cb, ID) {
connection.connect(function(err) {
connection.query("SELECT * FROM prices WHERE=" + "'" + ID + "'" ...
And then pass it when you call the function in app.js
var str = req.url;
var obj = str.split("&");
var ID = obj[0].split("/")[3];
db_connection.asyncGetAllData(function(data) {
...
}, ID);

Parse Promises Multiple httpRequest Cloud Code

I'm writing an iOs app with Parse.com and Cloud Code. Actually I want to retrieve objects which contain one picture and other informations from a website and I want to add them to a class named News. When I run my code, every object is saved (in my class, one row = one retrieved object) but unfortunately the only first one has its picture saved.... Any idea ?
I made a lot of searches about promises (series / parallels) and I think the problem comes from here..
Note : don't worry about myLink, myImgLink : I put this to make my code easy to read !
Parse.Cloud.define("rajouteNews", function(request, response) {
Parse.Cloud.httpRequest({ url: 'myUrl'}).then(function(httpResponse) {
var news = [];
var NewsClass = Parse.Object.extend("news");
for (var i = 0; i < 10 ; ++i) {
var maNews = new NewsClass();
maNews.set("link", myLink[i]); // "Other informations"
maNews.set("imgLink", myImgLink[i]);
maNews.set("title", myTitle[i]);
var promises = [];
promises.push(Parse.Cloud.httpRequest({
url: $('img').attr('src'),
method: 'GET',
}).then(function(httpResponse){
var imgFile = new Parse.File("photo.jpg", {base64:httpResponse.buffer.toString('base64')});
maNews.set("image",imgFile); // The picture
return maNews.save();
}));
news.push(maNews);
}
promises.push(Parse.Object.saveAll(news, {
success: function (list) {
response.success(news.length.toString() + " ont été sauvegardées");
},
error: function (list, err) {
response.error("Error adding news");
}
}));
return Parse.Promise.when(promises);
}).then(function(bla,result){
response.success("Job done");
}, function(error) {
response.error(error);
}
);
});
Your promises array should put out of the for loop scope. Otherwise , your promise array would be assigned to be a new blank array each loop.
Parse.File would be saved automaticly when its parent do save, you don't need to save it in advance.
So I improve your code as following, try it and tell me weather it works.
Parse.Cloud.define("rajouteNews", function(request, response) {
Parse.Cloud.httpRequest({
url: 'myUrl'
}).then(function(httpResponse) {
var promises = [];
var NewsClass = Parse.Object.extend("news");
for (var i = 0; i < 10; ++i) {
var maNews = new NewsClass();
maNews.set("link", myLink[i]); // "Other informations"
maNews.set("imgLink", myImgLink[i]);
maNews.set("title", myTitle[i]);
var maNewsPromise = Parse.Cloud.httpRequest({
url: $('img').attr('src'),
method: 'GET',
}).then(function(httpResponse) {
var imgFile = new Parse.File("photo.jpg", {
base64: httpResponse.buffer.toString('base64')
});
maNews.set("image", imgFile); // The picture
return maNews.save();
});
promises.push(maNewsPromise);
}
return Parse.Promise.when(promises)
}).then(function(bla, result) {
// this function is call when `Parse.Promise.when(promises)` is done,
//I can't figure out why you take two params.
response.success("Job done");
}, function(error) {
response.error(error);
});
});

better approach to access datatabase and creating models in cross platform apps

for example , i have been using following approach in my cross platform apps to accessing sqlite database as follows
To access database i have made a saperate .js for UserProfile table
function DBUserProfile()
{
this.selectUserName = function(userId, callback)
{
try
{
//Get Data
localDB.transaction(function selectUserProfileData(tx)
{
var objDBDatabaseSchema = new DBDatabaseSchema();
var sqlCommand = 'SELECT username FROM '
+ objDBDatabaseSchema.UserProfileMetaData.USER_PROFILE_TABLE_NAME
+' WHERE engineer_id='
+ '="' + userId + '"';
objDBDatabaseSchema = null;
tx.executeSql(sqlCommand,[],function selectUserNameResult(tx, results)
{
if (results.rows.length > 0 )
{
var userId = results.rows.item(0).username ;
callback(userId);
}
else
{
var userId = "";
callback(userId);
}
}, errorDB);
}, errorDB);
}
catch (e)
{
// TODO: handle exception
console.log("DBUserProfile - selectUserName " + e);
}
};
}
and this is how i use them in a pages
var objDBUserProfile = new DBUserProfile();
objDBUserProfile.selectUserName("3443" , function(id){
//
});
but the above approach is pretty time consuming i have been end up creating lot of models and db files to access tables and lot of new objects , so does anyone has a better approach in jquery to cut down the development time. any suggestions are welcome

html5sql - Can't seem to connect to my DB

I'm using html5sql.com for doing html5 DB stuff :o)
- Really a great module...
However, I got stuck!
At my index.html/index.js I create my database and tables in it.
try {
html5sql.openDatabase("com.dynamicvenues.fairkeyMobile.db","Questionnaire",3*1024*1024);
html5sql.process(
[
"CREATE TABLE IF NOT EXISTS Questionnaire (uid INTEGER, json TEXT, hash TEXT);",
"CREATE TABLE IF NOT EXISTS Answers (id INTEGER PRIMARY KEY, visitor_id TEXT, json TEXT);"
],
function(){
console.log("Success Creating Tables");
},
function(error, statement){
console.error("Error: " + error.message + " when processing " + statement);
}
)
} catch(error) {
alert("Database create failed: "+error.message);
}
And further in the same page I populate one table with data:
jQuery.get(serverHttp+"json.php?exhibitorID="+exhibitorID, function(data){
var html = $(data).map(function() {
return $(this).html();
});
var jsonStr = html[0];
var exhibitorID = html[1];
var hashStr = html[2];
var SQL = "INSERT INTO Questionnaire (uid, json, hash) VALUES ("+exhibitorID+",'"+jsonStr+"','"+hashStr+"')";
try {
html5sql.process(SQL,
function(){
console.log('Inserted 1 row!');
},
function(){
console.error("Error: " + error.message + " when processing " + statement);
}
)
} catch(error) {
alert("Query failed: "+error);
}
Now, in a different page called questionnaire.html/questionnaire.js I'm trying to retrieve the data I stored in the table Questionnaire.
html5sql.process(
["SELECT * FROM Questionnaire;"],
function(transaction, results, rowsArray){
for(var i = 0; i < rowsArray.length; i++){
var uid = rowsArray[i].uid;
var json = rowsArray[i].json;
var hash = rowsArray[i].hash;
console.log("Retrieved rows: "+uid+" - "+json+" "+hash);
}
console.log("Done selecting data");
},
function(error, statement){
console.error(error.message+" Occured while processing: "+statement);
}
);
What am I doing wrong???
Regards,
Daniel
Solved! Inserted: html5sql.openDatabase("com.dynamicvenues.fairkeyMobile.db","Questionnaire",3*102‌​4*1024); Before html5sql.process() at questionnaire.js

How do you make a request to google-api using node.js and Express? Getting Request is not defined Error

I am working on a node.js server and want to call the Google Shopping Service and retrieve results for a search query. I think I am applying the search query string correctly, but I am getting a 500 Reference Error: Request is not defined. My code is below:
googleShoppingService.js
//Shopping Search Factory
module.exports = function(productSearch){
return new productKey('---API-KEY-GOES-HERE---');
};
//constructor
function productKey(key) {
this.key=key;
}
// Search API
function toJSON(str){
var result;
try {
result=JSON.parse(str);
} catch(err){}
return result;
}
productKey.prototype.search = function (req, done) {
request.get('https://www.googleapis.com/shopping/search/v1/public/products')
.send({key:this.key})
.send({country:'US'})
.send({q:req.body.searchQuery.value})
.end(function (err, res) {
var body = toJSON(res.text);
var result = body && body.product || [];
return done(err, result);
});
};
app.js
var productSearch = require('./apis/googleShoppingSearch.js');
var products = productSearch('---API-KEY-GOES-HERE---')
app.get('/productResults', function(req, res){
products.search(process.argv[2], function (err, results) {
var returnedData = ""
for (var i=0;i < results.length; i++) {
returnedData += (results[i].title + '<br />')
}
res.send (returnedData)
});
});
Any suggestions to solve my problem would be greatly appreciated. Thanks for the help in advance.

Categories

Resources