passing vars from js to node - javascript

I have a button that when pressed I want it to send an array of objects (logs) from that js file to a node js file so I can then output a JSON file. I've tried AJAX with this tutorial and this one but I still don't understand how to pass a variable between js and node.
const done_but = document.getElementById("done");
var logs = []
var xhttp = new XMLHttpRequest();
document.getElementById('r2').checked = true;
done_but.onclick = function() {
const student = document.getElementById("student-drop").value;
const face = document.querySelector('input[name="faceses"]:checked').value;
const time = new Date();
logs.push([{
student: student,
face: face,
time: time.toUTCString()
}]);
xhttp.open("POST", "file:///(file path)/index.html");
xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
xhttp.send(logs);
console.log(logs);
};

I figured out that if you put your styles and local js into your HTML file you can write that to the screen then take any input from the local js. To give the server data you can
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:8000");
xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
xhttp.send(YourVar);
Here is my node code that takes the input and writes the screen.
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
fs.readFile('index.html', function(err, data) {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write(data);
res.end();
if (req.method === 'POST') {
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // convert Buffer to string
});
req.on('end', () => {
console.log(body);
console.log("");
res.end('ok');
});
}
});
}).listen(8000);
Helpful links:How to send JSON dataHow to send dataHandling requests

Related

How to stop number being converted to string in xmlHttpRequest?

How do I stop a number being converted to a string when adding an element to a JSON file on a server using xmlHttpRequest?
The following code updates my .json file with the element but the number (var importance) is a string by the time it arrives at the server... and I can't work out why.
This is where I format my input data and create the xmlHttpRequest.. (script.js):
btnSubmit.onclick = submitTask;
function submitTask() {
inputTask = document.querySelector('#task');
inputImportance = document.querySelector('#importance');
var task = inputTask.value;
var importance = Number(inputImportance.value);
console.log("User Input: ",task, importance);
//Setup XML HTTP Request
var xhr = new XMLHttpRequest();
xhr.open('POST', api_url_add +'/'+ task +'/'+ importance, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
//Receive response from server.
xhr.onload = function() {
response = JSON.parse(xhr.response);
console.log(response);
}
xhr.send();
}
And this is the server side code (server.js):
// ADD task to the list (task, importance)
app.post('/add/:task/:importance?', addTask);
function addTask(request, response) {
var data = request.params;
console.log('Submitted to server:','\n', data);
var task = data.task;
var importance = Number(data.importance);
var reply;
if (!importance) {
var reply = {
msg: "Importance value is required."
}
} else {
var element = data;
tasks['taskList'].push(element);
fs.writeFile('tasks.json', JSON.stringify(tasks, null, 2), function(err){
console.log('all done')
})
response.send(reply);
}
}
Thanks for all of your help.

How to handle JSON data from XMLHttpRequest POST, using nodeJS

Overarching goal is to save some JSON data I create on a webpage to my files locally. I am definitely sending something to the server, but not in format I seem to able to access.
JsonData looks like:
{MetaData: {Stock: "UTX", Analysis: "LinearTrend2"}
Projections: [2018-10-12: 127.62, 2018-10-11: 126.36000000000001, 2018-10-10: 132.17, 2018-10-09: 140.12, 2018-10-08: 137.73000000000002, …]}
XMLHttpRequest on my webpage:
function UpdateBackTestJSON(JsonUpdate){ //JsonUpdate being the JSON object from above
var request = new XMLHttpRequest();
request.open('POST', 'UpdateBackTestJSON');
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
// request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
request.onload = function() {
console.log("Updated JSON File");
};
console.log("about to send request");
console.log(JsonUpdate);
request.send(JSON.stringify(JsonUpdate));
}
and I handle posts on my server (rather carelessly I realize, just going for functionality as a start here)
var http = require('http')
, fs = require('fs')
, url = require('url')
, port = 8008;
var server = http.createServer (function (req, res) {
var uri = url.parse(req.url)
var qs = require('querystring');
if (req.method == 'POST'){
var body = '';
req.on('data', function (data){
body += data;
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
if (body.length > 1e6){
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
req.connection.destroy();
}
});
req.on('end', function () {
var POST = qs.parse(body);
console.log(POST); // PARSED POST IS NOT THE RIGHT FORMAT... or something, idk whats going on
UpdateBackTestData(POST);
});
}
function UpdateBackTestData(TheJsonData){
console.log("UpdateBackTestData");
console.log(TheJsonData);
JsonUpdate = JSON.parse(TheJsonData);
console.log(JsonUpdate["MetaData"]);
//var Stock = JsonUpdate["MetaData"]["Stock"];
// var Analysis = JsonUpdate["MetaData"]["Analysis"];
fs.writeFile("/public/BackTestData/"+Analysis+"/"+Stock+".json", TheJsonData, function(err){
if(err){
console.log(err);
}
console.log("updated BackTest JSON!!!");
});
}
Most confusing to me is that when I run this, the Json object Im am trying to pass, does go through to the server, but the entirety of the data is a string used as a key for a blank value in an object. when I parse the body of the POST, I get: {'{MetaData:{'Stock':'UTX','Analysis:'LinearTrend2'},'Projections':[...]}': ''}. So my data is there... but not in a practical format.
I would prefer not to use express or other server tools, as I have a fair amount of other services set up in my server that I don't want to go back and change if I can avoid it.
Thanks for any help

res.send is not a function

I am making an api call and recieving the data, however, I am having trouble sending the data back to my js file. I tried using res.send but I am getting an error. I can't seem to figure out how to send the information back to the javascript file. (I took my key out of the request link. For security reasons, however, I am getting the data back from the api call). The only problem I am having is returning the data to the frontend javascript file.
This is the Javascript file that sends the original request:
/ ********** options button function makes api call to get selected cities forecast *****************
function getCityForecast(e){
var id = document.getElementById('cities');
var getValue = id.options[id.selectedIndex].value;
var suffix = getValue + ".json";
var newObj = JSON.stringify({link : suffix});
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(newObj);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log(xhr.response);
console.log('recieved');
} else {
console.log('error');
}
}
}
My server.js file looks like this:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var http = require('http');
var path = require('path');
var request = require('request');
// ****************** Middle Ware *******************
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
var retrievedString;
// **************** Post Request *******************
app.post('/', function(req, res){
var link = "http://api.wunderground.com/api/key/forecast";
retrievedString = link.concat(req.body.link);
request = http.get(retrievedString , function(res){
var body = '';
res.on('data', function(data){
body += data;
});
res.on('end', function(){
var parsed = JSON.parse(body);
console.log(parsed.forecast.txt_forecast);
res.send(parsed.forecast.txt_forecast);
});
})
.on('error', function(e) {
console.log("Got error: " + e.message);
});
});
app.listen(3000, function() { console.log('listening')});
You are overloading the definition of the variable res which is also what you called the response variable for your Express route handler method. In the callback function of the request, use a different name for that variable - for example:
request = http.get(retrievedString , function(resDoc){

Node JS JSftp Get binary data, return string

I am relatively new on Node JS. I am working on an application fetching XML-files from a server.
In summary I want to do this:
Download XML-files from FTP server and store the XML-content as a
string.
Return the string to the browser as plain text.
I am able to use jsftp.get to download files to a local directory, but I am not able to get the downloaded data as a string.
What am I doing wrong?
My code is like this:
var http = require("http");
var url = require("url");
var JSFtp = require("jsftp");
var myStrToReturn = new String();
http.createServer(function(req, res) {
// URL
var parsedUrl = url.parse(req.url, true);
var queryAsObject = parsedUrl.query;
var str = new String();
var myFunction = queryAsObject["function"];
var Ftp = new JSFtp({
host: "ftp.ftp.ftp",
port: 21, // defaults to 21
user: "user", // defaults to "anonymous"
pass: "passwd", // defaults to "#anonymous"
debugMode: true
});
var str = "";
Ftp.get("Production/Offers/datafile.xml", function(err, socket) {
if (err) return;
socket.on("data", function(d) { str += d.toString(); })
socket.on("close", function(hadErr) {
if (hadErr)
console.error('There was an error retrieving the file.');
});
socket.resume();
});
myStrToReturn = str.toString("binary");
res.writeHead(200, {
'Content-Encoding':'utf-8',
'charset' : 'utf-8',
'Content-Type': 'text/plain;charset=utf-8'});
res.write(myStrToReturn.toString());
res.end();
console.log(myStrToReturn);
});
Ftp.on('jsftp_debug', function(eventType, data) {
console.log('DEBUG: ', eventType);
console.log(JSON.stringify(data, null, 2));
});
}).listen(8030);
console.log("Server listening on port 8030");
Download is asynchronous so when you reach to
myStrToReturn str.toString("binary");
its value is undefined this is why you will get an error when you are trying to use toString.
Solution for that is to use promises or use the mystrToReturn only inside socket.on("close",...

Nodejs output -Domain name not found

Technically this is my first try in nodejs and frankly I am not sure if I am doing it right. I am creating a local server that will stream the output from a distant server. However, when I run my code and I enter a URL in the browser, the program fails with the following message:
events.js:45
throw arguments[1]; // Unhandled 'error' event
^
Error: ENOTFOUND, Domain name not found
at IOWatcher.callback (dns.js:74:15)
The URL I used was: 127.0.0.1:9000/http://www.yahoo.fr. And in the browser I had the following message:
No data received
Unable to load the webpage because the server sent no data.
Here are some suggestions:
Reload this web page later.
Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.
Any help is greatly appreciated.
Here is the code:
var base, dest, node_client,
count = 0,
url = require('url'),
util = require('util'),
http = require('http'),
http_client = require('http'),
request = require('request'),
events = require('events'),
httpProxy = require('./lib/node-http-proxy'),
data_emitter = new events.EventEmitter();
httpProxy.createServer(9000, 'localhost').listen(8000);
http.createServer(function (req, res) {
if(!count)
{
base = url.parse(req.url).pathname;
node_client = http_client.createClient(80, base);
count++;
} else {
dest = req.url.substr(1, req.url.length -1);
}
request = node_client.request("GET", dest, {"host": base});
request.addListener("response", function (response) {
var body = "";
response.addListener("data", function (data) {
body +=data;
});
response.addListener("end", function () {
var out = JSON.parse(body);
if(out.length > 0) {
data_emitter.emit("out", out);
}
});
});
// request.close();
var listener = data_emitter.addListener("data", function(out) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(JSON.stringify(out));
res.close();
});
}).listen(9000);
Wild guess : your browser automatically requests 127.0.0.1:9000/favicon.ico and your program then tries to resolve favicon.ico which obviously fails and makes your program crash before it can send any data for the real request.
Why such tangled code?
This is a scenario where it makes sense to avoid nested callbacks, and use named functions. If you refactor the code, then people are more likely to be help you.
Can you do console.log(out) in your listener callback? Let us know if Node.js has any response data to return.
Well, for any newbie like me in this area, here is how I solved it. It's not clean and can be implemented in better way. Feel free to change, give suggestions.
Code:
var url = require('url'),
http = require('http'),
request = require('request'),
httpProxy = require('./lib/node-http-proxy'),
des = '',
util = require('util'),
colors = require('colors'),
is_host = true;
httpProxy.createServer(9000, 'localhost').listen(8000);
var server = http.createServer(function (req, res) {
var pathname = '';
if(is_host) {
dest = req.url.substr(0, req.url.length -1);
pathname = dest;
is_host = false;
} else {
pathname = req.url.substr(0, req.url.length);
if(pathname.charAt(0) == "/") {
console.log('new request');
console.log(pathname);
pathname = dest + pathname;
}
}
console.log(pathname);
request.get({uri: pathname}, function (err, response, html) {
res.end(html);
});
console.log('fetched from ' + pathname);
});
server.listen(9000);

Categories

Resources