Running node.js proccess step by step - node.js

I was a PHP developer, I'm trying to write code using node.js for praticing. M am confuse about node.js when I execute my program, line of code jump to next line.
This is the part of my code:
//article.js
var article_model = require('../models/article_model');
var comment_model = require('../models/comment_model');
var list_article,list_comment;
app.set('views','./views/article/');
app.set('view engine','ejs');
app.get('/list_article',csrfProtection,function(req,res){
master_model.get_article(req,xparams,function(status,result,total_data){
list_article = result.data;
});
console.log(list_article);
master_model.get_comment(req,xparams,function(status,result,total_data){
list_comment = result.data;
});
console.log(list_comment);
var params = {
title : "Article List",
data_article : list_article,
};
res.render('content.ejs',params);
});
and then
//master_model.js
exports.get_article = function (req,hash, fn) {
var auths = {
user : api_server["auth_username"],
pass : api_server["auth_password"],
}
request.get({url:"http://myapi.com/article/latest", auth:auths } , function(err,httpResponse,body) {
if (!err && httpResponse.statusCode == 200) {
var temp = JSON.parse(body);
if (temp.status == 1){
result_data = {status:1, message : temp.message ,data : temp.data};
return fn(true,result_data,1);
}else if(temp.status == 0){
result_data ={ status:0, message : temp.message};
return fn(false,result_data,0);
}
}else{
result_data ={ status:0, message : "error, please try again"};
return fn(false,result_data,0); //something problem to API
}
})
};
exports.get_comment = function (req,hash, fn) {
var auths = {
user : api_server["auth_username"],
pass : api_server["auth_password"],
}
request.get({url:"http://myapi.com/comment/latest", auth:auths } , function(err,httpResponse,body) {
if (!err && httpResponse.statusCode == 200) {
var temp = JSON.parse(body);
if (temp.status == 1){
result_data = {status:1, message : temp.message ,data : temp.data};
return fn(true,result_data,1);
}else if(temp.status == 0){
result_data ={ status:0, message : temp.message};
return fn(false,result_data,0);
}
}else{
result_data ={ status:0, message : "error, please try again"};
return fn(false,result_data,0); //something problem to API
}
})
};
when i run my code, and open browser, output data is blank, when i refresh again my browser show ouput my data (artcile list, and commment list)
and i look my console if first run
output : {
id : 1
title : title 1..
...
..
}
undefined
If i refresh my browser again, all output complete to show (not show undefined)
My question:
How to make my code run the process step by step until the process end and deliver to views?
Any problem with my code?
Thanks!

To address your initial question properly, you can actually go step by step, using breakpoints. In the latest node 7 and now 6 you can use Chrome Dev Tools to debug a node application. You need to set some breakpoints and watch variables to help you understand:
execution order
the precise values of variables at key moments
I still think breaking the big program into smaller programmes would be helpful and reduce surprises, but learning to debug properly is also really useful!
You just run the program with node --inspect index.js, and then a link will be displayed on the console that you load up in Google Chrome Browser.
There is a more thorough guide, which might help.
The official documentation is also worth a read.

Related

Chrome Plugin Manifest V3 - strange behavior of a promise function in popup.js

I'm trying to create a small plugin to make my day-to-day job easier. I have faced a very strange situation within the popup.js script. The promise function randomly refuses to get executed. I have spent some hours trying to debug or at least understand where the issue could be but without any results.
Here is the skeleton of the code:
document.addEventListener('DOMContentLoaded', function () {
// some initialization
document.getElementById("signinbutton").addEventListener("click", function(event) {
try {
// some more initialization
var user_email = '';
var advertiserId = '';
var checkibm = '';
user_email = $('#emailfield').val().trim();
advertiserId = $('#advertiseridfield').val().trim();
checkibm = $('#checkibm').is(':checked');
if (advertiserId && checkibm) {
_act = 'getTokenIdByAdvId',
_data = advertiserId
}
else if (advertiserId && !checkibm) {
_act = 'getTokenIdByAdvId',
_data = advertiserId
}
else if (user_email && validateEmail(user_email))
{
_act = 'getTokenIdByEmail',
_data = user_email
}
else
{
throw new Error("Valid input has not been provided");
}
sendMessagePromise({
act : 'getTokenIdByAdvId',
data: '16910'//encodeURIComponent(user_email)
})
.then(responseHandler)
.then(responseReplaceTokenHandler)
.then(show_ok('Done'))
.catch(failureCallback);
}
catch (error){
//doing some error catching here
});
});
The code above works perfectly. However, as soon as I fill in the real values in sendMessagePromise e.g
//_act and _data show the proper values when inspected
sendMessagePromise({
act : _act,
data: _data//encodeURIComponent(user_email)
})
the flow skips execution of sendMessagePromise and any other chained function, except the last one ".then(show_ok('Done'))", i.e the only result is the "Done" message on the screen.
I made sure the values are correct. I'm able to debug step-by-step and see the values being properly supplied. I have also put a bunch of console messages inside the chain promise functions to see where the execution gets stuck, but it seems like it doesn't even start executing sendMessagePromise.
As soon as I replace expression back to hardcoded values i.e
sendMessagePromise({
act : 'getTokenIdByAdvId',
data: '16910'//encodeURIComponent(user_email)
})
it starts working again. I'm really stuck and not sure how to debug or which steps to take further.
Please assist

Mongoose updateOne() stops working. No errors thrown

Hello and thank you for taking a look at this.
I have a scheduled function that contacts an API and is supposed to save the data to a local DB. It works several times and then stops saving. I have confirmed that the functions are executing per their scheduled times. Mongoose does not save the data and does not give me an error.
2 part request:
I would love help trying to catch and log the error.
-Maybe my logger(s) are in the wrong location?
Also, if you have any insight as to why it works when I start the
server and then eventually stops working that would be appreciated as
well.
-Maybe I am not 'returning' the functions properly?
Get the data from the API:
function updateWeather(){
const weatherurl = 'https://api.aerisapi.com/observations/pendleton,or?&format=json&filter=allstations&limit=1&client_id=bRZUxQc8j4z41CrH7SM6u&client_secret=GaEA7lMyLKnQwRsUcxv1mnNhTUkx6KUtVsrIXVcR';
axios.get(weatherurl)
.then(response=>{
// console.log(response.data);
let condition = response.data.response.ob.weather,
temp = response.data.response.ob.tempF,
windDir = response.data.response.ob.windDir,
windSpd = response.data.response.ob.windSpeedMPH,
windGust = response.data.response.ob.windGustMPH,
windChill = response.data.response.ob.windchillF,
humidity = response.data.response.ob.humidity,
icon = response.data.response.ob.icon,
date = moment().utcOffset(-8).format('YYYY-MM-DD'),
updated = moment().utcOffset(-8).format('MM/DD/YY HH:mm');
if(temp <= 35){
var tempIcon = 'https://cdn.aerisapi.com/wxicons/v2/cold.png';
}else if(temp >= 80){
var tempIcon = 'https://cdn.aerisapi.com/wxicons/v2/hot.png';
}else{
var tempIcon = '';
}
currentWeather.push({date:date, condition:condition, temp:temp, windChill:windChill, windDir:windDir, windSpd:windSpd, windGust:windGust, humidity:humidity, icon:icon, tempIcon:tempIcon, updated:updated});
return currentWeather[0]
}).then(currentWeather=>{
// console.log(currentWeather);
saveWeather(currentWeather);
}).catch(error=>{
logger.error(error);
});
return currentWeather;
}
Save data to DB:
function saveWeather(weather){
logger.info('saveWeather connection status: '+mongoose.connection.readyState);
if(mongoose.connection.readyState !== 1){
mongoose.connect("mongodb://localhost:27017/fdData", {useNewUrlParser: true});
}
Weather.updateOne({date: weather.date}, {date:weather.date, condition:weather.condition, temp:weather.temp, windChill:weather.windChill, windDir:weather.windDir, windSpd:weather.windSpd, windGust:weather.windGust, humidity:weather.humidity, icon:weather.icon, tempIcon:weather.tempIcon, updated:weather.updated}, {upsert:true}, error=> {
if (error){
logger.error(error);
} else{
logger.info('Weather Saved to DB')
}
})
return weather;
}
Thanks again!
-Adam

Parse.com set class default attributes

I have been working with Parse Cloud Code, and I have not achieved setting default values for my classes. Right now I am doing this:
Parse.Cloud.beforeSave('MyClass',function(request, response){
//The description should only have 200 characters
if(request.object.get('description')){
var des = request.object.get('description');
if(des.length>200){
request.object.set("description", des.substring(0, 197) + "...");
}
}
//let's make a default value
if(typeof request.object.get('active') === 'undefined'){
request.object.set('active',false);
}
response.success();
});
When I upload this function to the Cloud Code, and try to create a new object from the dashboard it wont have the default value active = false.
I don't know what's going on. Has somebody achieved this before?
My code is very similar to the one in the Parse docs. They say this could be done like this:
Parse.Cloud.beforeSave("Review", function(request, response) {
var comment = request.object.get("comment");
if (comment.length > 140) {
// Truncate and add a ...
request.object.set("comment", comment.substring(0, 137) + "...");
}
response.success();
});
However, for me it doesn't want to work.
Wohoo! I did it!
Nowhere in the documentation is said that if you want to do so, you must return the object you edited in the response.success().
Solution:
Parse.Cloud.beforeSave('MyClass',function(request, response){
//The description should only have 200 characters
if(request.object.get('description')){
var des = request.object.get('description');
if(des.length>200){
request.object.set("description", des.substring(0, 197) + "...");
}
}
//let's make a default value
if(typeof request.object.get('active') === 'undefined'){
request.object.set('active',false);
}
response.success(request.object); //this is the line that changes
});

How do I stop a table script from processing?

I am creating an insert script that does some business logic.
Basically, I want to check to see if a value in the inserted item exists in a table. But, it seems like if I find a problem Request.Send() doesn't stop execution and get an error.
I think there is an async issue here. I'm not 100% sure how to solve.
Is there a way to stop execution of the script?
if (item.memberType === 'Family' && item.primaryFamilyMember) {
table
.where({
memberNumber: item.primaryFamilyMember,
memberType: 'Family',
primaryFamilyMember: null })
.read({
success: function(results) {
if (results.length == 0) {
request.respond(statusCodes.BAD_REQUEST,
'Invalid Primary Family Member specified.');
console.error('Invalid Primary Family Member specified:' + item.primaryFamilyMember);
validInsert = false;
} else {
item.memberType = results[0].memberType;
item.memberLevel = results[0].memberLevel;
item.dateOfExpiry = results[0].dateOfExpiry;
}
}
});
}
if (validInsert) {
var today = new Date();
var prefix = today.getFullYear().toString().substr(2,2) + ('0' + (today.getMonth() + 1)).slice(-2);
table.includeTotalCount().where(function(prefix){
return this.memberNumber.substring(0, 4) === prefix;
}, prefix)
.take(0).read({
success: function (results) {
if (isNaN(results.totalCount)) {
results.totalCount = 0;
}
item.memberNumber = prefix + ('00' + (results.totalCount + 1)).slice(-3);
request.execute();
}
});
}
Yes, validInsert is declared at the top of the insert function.
I assume what's happening is the if(validInsert) runs before the read callback. But if so, i'm not sure why I'm getting "Error: Execute cannot be called after respond has been called." That implies the callback is running first.
Also, the record is being inserted when it shouldn't be even though the 400 error is sent back to the client.
This is an express app right? Should I just call response.end() after the error occurs?
Yes, there are definitely asyn issues in that code. To solve get rid of your validInsert flag and simply move the if (validInsert) section into the success callback (or make it a function called from the success callback). For example:
success: function(results) {
if (results.length == 0) {
request.respond(statusCodes.BAD_REQUEST,
'Invalid Primary Family Member specified.');
console.error('Invalid Primary Family Member specified:' + item.primaryFamilyMember);
} else {
item.memberType = results[0].memberType;
item.memberLevel = results[0].memberLevel;
item.dateOfExpiry = results[0].dateOfExpiry;
var today = new Date();
var prefix = today.getFullYear().toString().substr(2,2) + ('0' + (today.getMonth() + 1)).slice(-2);
...
//respond successfully
}
}

object stocking in node.js

How can I create resuable blank objects in node.js? For example :
In file1 :
var Result = {
error :false,
errorReport :[]
}
exports.Result = Result;
In file 2 :
var result = require('../file1');
exports.doSomething = function(){
var output = result.Result;
output.error = true;
output.errorReport = some_error_array;
}
Now, everytime I invoke doSomething(), it is obvious that the last result will be cached.
But, everytime I invoke doSomething(), i want a fresh object as it is declared in Result without any extra programming (i dont want to reset attributes everytime i do some thing with Result object.
Am I missing any minor detail here ? please help me out
You could make it a class:
exports.Result = function() {
this.error = false;
this.errorReport = [];
};
// later on:
var output = new result.Result();
...
Or even make it fancy so that you can pass arguments:
exports.Result = function(error, errorReport) {
this.error = error === undefined ? false : error;
this.errorReport = errorReport === undefined ? [] : errorReport;
};
// later
var output = new result.Result(true, some_error_array);

Resources