So for some reason all of a sudden after I move my print functions to their own file and try to run the node command on my app.js file then it doesn't want to print anything in my console. Why is that?
I am still struggling with debugging this one as nothing is printing out when I run the following command.
node app.js myusernamehere
Anyone have any idea?
app.js
var profile = require("./profile.js");
var users = process.argv.slice(2);
users.forEach(profile.get);
profile.js
//Problem: We need a simple way to look at a user's badge count and Javascript points
//Solution: Use Node.js to connect to Treehouse's API to get profile information to print out
var https = require("https");
var http = require("http");
var printer = require("./printer.js");
function get(username) {
//Connect to API URL (http://teamtreehouse.com/username.json)
var request = https.get("https://teamtreehouse.com/" + username + ".json", function(response) {
var body = "";
//Read the data
response.on('data', function(chunk) {
body += chunk;
});
response.on('end', function() {
if (response.statusCode == 200) {
try {
//Parse the data
var profile = JSON.parse(body);
//Print the data
printer.printMessage(username, profile.badges.length, profile.points.JavaScript);
} catch(error) {
//Parse Error
printer.printError(error);
}
} else {
//Status Code Error
printer.printError({message: "There was an error getting the profile for " + username + ". (" + http.STATUS_CODES[response.statusCode] + ")"});
}
});
});
//Connection Error
request.on('error', printer.printError);
}
module.exports.get = get;
printer.js
//Print out message
function printMessage(username, badgeCount, points) {
var message = username + " has " + badgeCount + " total badge(s) and " + points + " points in Javascript";
console.log(message);
}
//Print out error messages
function printError(error) {
console.error(error.message);
}
module.exports.printMessage = printMessage;
module.exports.printError = printError;
I don't know what actually happened but it works now and nothing in my code was changed.
Related
I'm getting the value 'undefined' concatenated to my original data when calling the HTTPS response data
This is for calling a URL and getting the response data
```javascript
url = "xxxxxxxx"; //url is anonymous, so cant disclose
function externalApi(url){
try{
var https = require('https');
var request = https.request(url, function (response) {
var str;
var statusCode;
response.on('data', function (data) {
str += data;
statusCode = response.statusCode;
});
response.on('end', function () {
console.log("Data is " +str);
console.log("Status Code is " +statusCode);
});
request.on('error', function (e) {
console.log('Problem with request: ' + e.message);
console.log('Problem with request: ' + e);
});
request.end();
} catch(err){
console.log("the error is" + err);
}
}
I expect the output to be {"MESSAGE":"No log found for ID 2"} but what i get is undefined{"MESSAGE":"No log found for ID 2"}
When you use += with a string, you're concatenating values. [un]Fortunately javascript doesn't blow up when you concat an undefined variable, but it doesn't ignore it either.
In your case, you're declaring var str but you're not initializing it with a value before concat-ing onto it. If you initialize it with a value, ie: var str = '': it would no longer show undefined before the message.
IE:
// your code...
var request = https.request(url, function (response) {
var str = ''; // this way it's not undefined
var statusCode;
response.on('data', function (data) {
str += data;
statusCode = response.statusCode;
});
// the rest of your code...
You are concatenating uninitialized variable with response str += data;.
You should initialize variable as empty string at the beginning.
var str = '';
Change:
str += data;
to:
str = data;
I'm adding a contact me section to a website. I want to be able to send the data from the forms with JS, and then receive and do something with the data with Node. I understand that there are frameworks and libraries that can handle this stuff, but I would like to build it from scratch so that I have a better understanding of what is happening.
I currently have a section of JS (see below) that is taking the form data, and sending it as a POST request to the node script, but I can't seem to wrap my head around what is happening with node, or how to receive the data with the node script. Any help in pointing me in the right direction is greatly appreciated.
const name = $(".name");
const email = $(".email");
const message = $(".message");
const submitButton = $(".submitButton");
const nameRegex = /([a-zA-Z\s-])/g;
const emailRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/g;
const messageRegex = /([a-zA-Z\s.,?!$%&])/gm;
const url = "../node/contactMeSubmissionHandler.js"
submitButton.click(function(){
let nameContents = name.val().match(nameRegex).join("");
let emailContents = email.val().match(emailRegex).join("");
let messageContents = message.val().match(messageRegex).join("");
// if (emailRegex.test(emailContents) == true) {
// let emailValid = emailContents;
// } else {
// console.log("Email is invalid");
// };
const data = {
email: emailContents,
name: nameContents,
message: messageContents
}
$.post(url, data, function(data, status){
console.log(`${data} and status is ${status}`);
})
})
I like to write from scratch too. Here is working code which is called from a command line to get a token.
// clientEx.js
var http = require('http');
var fs = require('fs');
const _SERVER = "dcsmail.net"; /* dcsmail.net */
// Callback function is used to deal with response
//
var callback = function (response)
{
// update stream with data
var body = '';
response.on('data', function(data) {
body += data;
});
response.on ('end', function()
{
// Data received completely.
fs.writeFileSync ("temp.lst", body, 'utf8');
// console.log ("clientEx.js received: " + body);
});
}
if ((process.argv[2] == null) || (process.argv[3] == null) || (process.argv[4] == null) || (process.argv[5] == null))
{
console.log ("clientEx.js usage:<user email> <user password> <destination> <GUID>");
}
else
{
var Ef_email = encodeURI (process.argv[2]);
var Ef_pass = encodeURI (process.argv[3]);
var Ef_dest = encodeURI (process.argv[4]);
var Ef_guid = encodeURI (process.argv[5]);
var post_data = ("f_email=" + Ef_email +
"\&" + "f_pass=" + Ef_pass +
"\&" + "f_dest=" + Ef_dest +
"\&" + "f_guid=" + Ef_guid);
// Options to be used by request
var options = {
host: _SERVER,
port: '80',
path: '/DCSM/tokenP10.php',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength (post_data)
}
};
// console.log ("clientEx.js using " + _SERVER + ":" + options.port + options.path);
// request the token from the host
try
{
var req = http.request (options, callback);
req.write (post_data);
req.end();
}
catch (error)
{
fs.writeFileSync ("temp.lst", "Host access failed\n", 'utf8');
}
}
You should be able to adapt that to your needs.
Use this code to create a server and check the log in console for different request attributes.
const http = require('http');
http
.createServer((request, response) => {
console.log(request);
response.end();
})
.listen(3000);
Make GET and POST request to http://localhost:3000/ and look for method, headers etc.
See more here and here.
Friends,
Currently I'm implementing twitch.tv app using json as my part of my freecodecamp course. Using twitch api, I have to call json twice, to get user and stream data. I also do this in the loop, as I have multiple streamers I want to follow. Here you can see my code.
$(document).ready(function() {
var streamerList = ["MisterRogers","freecodecamp"];
getStream(streamerList);
});
function getStream(streamerList) {
for (var k = 0; k < streamerList.length; k++) {
var userURL = makeURL("users", streamerList[k]);
var streamURL = makeURL("streams", streamerList[k]);
$.getJSON(userURL, function(data) {
var displayName = data.display_name;
var logo = data.logo;
$.getJSON(streamURL, function(data){
var status, game;
console.log(data);
if (data.stream === null){
status = 'Offline';
game = 'No Content Available';
} else if (data.stream === undefined){
status = 'Not available'
game = 'Channel Closed';
} else {
status = 'Online';
game = data.stream.game;
}
addRow(displayName, logo, status, game);
});
});
}
}
In the example I use two streamers (freecodecamp and Mister Rogers), one of them is online, and the other offline. However, the data at the second json call is being messed up and in my app I see them both as offline. Its working fine if I remove freecodecamp or Mister Rogers and leave only one streamer. But two or more are not working. I'm quite new to js, so if you could explain the gaps in my logic, I would be very grateful. Cheers.
I managed to solve this problem by myself with some examples I found on internet. The problem with this code was that in the $(document).ready(function(){}) I pass string array streamerList as an argument for getStream() function, however, the streamerList variable is not seen within the second call of JSON (look at the code above). Because that call is in the function of first JSON call. Due to this reason, streamURL in the second call becomes undefined. To solve this issue I had to make variable streamerList global and run foreach loop. Here is my working solution:
var streamerList = ["MisterRogers", "freecodecamp"];
function getStream() {
streamerList.forEach(function(channel) {
function makeURL(type, streamer) {
return (
"https://wind-bow.gomix.me/twitch-api/" +
type +
"/" +
streamer +
"?callback=?"
);
}
$.getJSON(makeURL("streams", channel), function(data) {
var status, game;
if (data.stream === null) {
status = "Offline";
game = "No Content Available";
} else if (data.stream === undefined) {
status = "Not available";
game = "Channel Closed";
} else {
status = "Online";
game = data.stream.game;
}
console.log(status, game);
$.getJSON(makeURL("users", channel), function(result) {
var displayName = result.display_name;
var logo = result.logo;
addRow(displayName, logo, status, game);
});
});
});
}
function addRow(displayName, logo, status, game) {
var divRow = document.createElement("div");
divRow.className = "row";
divRow.innerHTML =
'<div class="col-md-4"></div>\
<div class="col-md-1"><img src="' +
logo +
'"/></div>\
<div class="col-md-3"><blockquote>\<p>\
<a href="http://www.twitch.tv/' +
displayName +
'" target="_blank">' +
displayName +
'</a></p>\
<footer><cite title="Source Title">' +
status +
": " +
game +
'</cite></footer></blockquote></div>\
<div class="col-md-1></div>';
document.getElementById("content").appendChild(divRow);
}
$(document).ready(function() {
getStream();
});
So, I want to request something from external api that is using TOTP. I have everything set up the right way and! On my localhost everything works fine, but on remote server - VPS - it crashes and gives following error :
{
"status" : "success",
"data" : {
"error_message" : "API access enabled, but unable to verify two-factor authentication code. If you need help with this, please contact support#bitskins.com."
}
}
HTML :
// Secret and keys for Bitskins API
var totp = new TOTP('MPKXR23QBRQVW7SZ');
var codeFromSecret = totp.now();
var url = 'https://bitskins.com/api/v1/get_item_price/?api_key=' + bitskins.apikey + '&code=' + totp.now() + '&names=' + namesHashed + '&delimiter=!END!';
console.log("url " + url);
request(url, function (error, response, body) {
if (!error) {
var json = JSON.parse(body);
console.log("body " + body);
console.log("json " + json);
for (var a = 0; a < items.length; a++) {
itemPrices.push(json.data.prices[a].price);
}
console.log('about to emit pricesFetched # steambot.js');
lastStep(itemPrices);
}
});
I have recently set up node.js using Express and I created a simple HTML form using Jade. The form is to insert the data in a PostgreSQL database. The problem is that when I press submit on the form, everything is inserted on the database, but the HTML form is just hanging/lingering, and at some point it stops with No data received, ERR_EMPTY_RESPONSE. Sometimes it also inserts the data twice. I guess this is because the server side does not return a response, but I cannot see how (I am new to node.js).
The form has action="add_device" which is routed to routes/add_device.js. add_device.js looks like this:
var express = require('express');
var router = express.Router();
router.get('/', function(request, response, next) {
res.send('Nothing to see here. Move along.');
});
router.post('/', function(request, response, next) {
var db = require('../public/javascripts/db/insert');
var result = db.insertDevice(request, response);
return result;
});
module.exports = router;
The insertDevice function in my db module looks like this (it is exported with module.exports):
// Insert new QA device. Data arriving as a request from a HTML form.
insertDevice: function (request, response) {
// Input that is verified in the HTML form.
// Convert to proper format for PostgreSQL query.
var name = '\'' + request.body.name + '\'';
var ip_address = '\'' + request.body.ip_address + '\'';
var os = '\'' + request.body.os + '\'';
// Input that needs to be verified. Prepare for PostgreSQL query.
var mac_address;
var os_version;
request.body.mac_address == "" ? mac_address = 'NULL' : mac_address = '\'' + request.body.mac_address + '\'';
request.body.os_version == "" ? os_version = 'NULL' : os_version = '\'' + request.body.os_version + '\'';
var pg = require('pg'); // PostgreSQL module.
var td = require('./table_data') // Database constants.
var client = new pg.Client(request.app.get('postgreConnection'));
client.connect(function(err) {
if (err) {
return console.error('Could not connect to postgres', err);
}
var QUERY = "INSERT INTO " + td.QA_DEVICES.TABLE_NAME + "(" +
td.QA_DEVICES.COLUMN_NAME + ", " +
td.QA_DEVICES.COLUMN_MAC_ADDRESS + ", " +
td.QA_DEVICES.COLUMN_IP_ADDRESS + ", " +
td.QA_DEVICES.COLUMN_OS + ", " +
td.QA_DEVICES.COLUMN_OS_VERSION + ") VALUES(" +
name + ", " +
mac_address + ", " +
ip_address + ", " +
os + ", " +
os_version + ");";
client.query(QUERY, function (err, result) {
if (err) {
return console.error('Error running query: ' + QUERY, err);
}
console.log('Query performed: ' + QUERY);
client.end();
});
});
}
The 'Query performed' is always logged to console and data inserted into the database, but the form is still hanging. My questions are:
Is it the lack of response from the server that makes the form hang?
How can I "send a response back" to the front end?
Is it possible to route the front end to another page after insertion into the database? What is the best practice?
Yes, your request is receiving no response, so it is hanging.
In order to send a response, you can either send a blind acknowledgement right when the request is received (that is not dependent upon the success of the query and may be bad practice), or you can send it in the callback.
client.query(QUERY, function (err, result) {
if (err) {
// response.json({status: 'error'});
response.write('Error');
return console.error('Error running query: ' + QUERY, err);
} else {
// You can send json here too
// response.json({status: 'success'});
response.write('Success');
}
console.log('Query performed: ' + QUERY);
client.end();
});
If you want to go to another page, simply parse the incoming response on the client side and do a redirect. Using json is a good way to carry this out. You can also do a response.redirect(url) on the server side too, instead of sending back data. Have fun