I am working on a complex program which involves uploading an excel sheet, creating a table and then work with the data in the table.
I must read first column of all rows and for every string, I must perform API call to the server.
The API request is performed as following:
async function main()
{
var id = await GOR_login();
console.log(id)
var result = await Gor_completed_actions(id,"RUT240");
console.log("emmiting result123=",result)
}
I used async and await functions to ensure that I get the result before I pass it to another function. For example GOR_login() is going to perform API GET request and if I do not use away, the data in console.log(id) will be undefined. I am not sure whether that is a correct way of doing.
Both API request functions GOR_login() and Gor_completed_actions are using node.js module fetch-node. I would like to call these functions in my html file after my table is being created, but I must somehow import fetch-node module to the html file.
Please check this JS fiddle:
http://jsfiddle.net/v04k3w7j/.
After uploading the excel document, it will create a table and fill the array codes_to_updt [] . This array tells me what API calls I need to make. After that, I must execute the function for the API calls:
async function main()
{
var id = await GOR_login();
console.log(id)
var result = await Gor_completed_actions(id,codes_to_updt); // call with codes_to_updt one by one
console.log("emmiting result123=",result)
}
The issue for me that I am not able to use fetch methods in .html file. In my .js file I do:
var fetch = require("node-fetch");
But it does not allow me to do that in .html.
Can someone clarify me what is the best solution to this problem?
UPDATE1 I hide the URL just for security reasons
Inside my .html, I try to use the following function for my html get request:
function httpGetAsync(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
And then this function is being called after the my array is filled:
httpGetAsync(URL_start_session);
The error is returned:
Access to XMLHttpRequest at 'my_url' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Trying to upload and parse the excel on node(server) side.
I have downloaded an xlsx module and with the following code, I am able to parse the excel document:
var XLSX = require('xlsx')
var workbook = XLSX.readFile('gor_plan2.xlsx');
var sheet_name_list = workbook.SheetNames;
var xlData = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);
console.log(xlData);
The console.log output returns me data:
[
{ Produkto_kodas: 'Product1', Kiekis: 50 },
{ Produkto_kodas: 'Product2', Kiekis: 295 },
{ Produkto_kodas: 'Product3', Kiekis: 244 },
{ Produkto_kodas: 'Product4', Kiekis: 225 },
{ Produkto_kodas: 'Product5', Kiekis: 17 }
]
Now I try to build a table out of this data.
How can I convert the JSON object data xlData into something html like :
<tbody>
<tr>
<th>Produkto kodas</th>
<th>Kiekis</th>
</tr>
<tr>
<td>Product1</td>
<td>50</td>
</tr>
<tr>
<td>Product2</td>
<td>295</td>
</tr>
<tr>
<td>Product3</td>
<td>244</td>
</tr>
<tr>
<td>Product4</td>
<td>225</td>
</tr>
<tr>
<td>Product5</td>
<td>17</td>
</tr>
</tbody>
</table>
I think you can't import Node modules on PureJS. But you can try calling a NodeJS function like this:
Note: I'm using express.js, hope this is not a problem for you.
//index.js
const expressjs = require("express")
const app = expressjs();
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
app.get("/", (req, res) => {
res.render("index.html");
});
app.get("/resources", (req, res) => {
func()
});
function func() {
var XLSX = require("xlsx")
}
app.listen(port, () => {
console.log("Listening")
}
HTML Server-Side:
<script>
var url = "http://ip:port/resources"
async function nodecall() {
fetch(url)
}
</script>
<button id="tap" onclick="nodecall()">Call NodeJS</button>
If you want to pass a variable from server-side to client-side you can do something like this:
NodeJs:
app.get("/resources", (req, res) => {
var variable = req.query.var
var variable2 = req.query.var2
});
HTML:
var url = "http://ip:port/resources?var=hello&var2=world"
And if you want to do the opposite. Client to Server...
NodeJs:
app.get("/resources", (req, res) => {
var string = "Hello World"
return res.send(string)
});
HTML:
let variable = await(await fetch(url)).text()
Remember to put HTML files in a folder named "views".
You can combine all of them if you want to. Hope this helped. Bye!
Related
I'm working on an OAuth2 Discord login to my game's index. I try to pull nickname to my client-side and my Discord bot directly change logged user's nickname to his game name. I have nickname on my PHP-based server-side with JSON data but I don't know how can I pull it to my client-side
Example PHP Code
$myobj->username = "Test";
$myJSON = json_encode($myobj);
echo $myJSON;```
And my Javascript code:
const express = require('express');
const Discord = require('discord.js');
const client = new Discord.Client();
const app = express();
const passport = require("passport");
const { Strategy } = require("passport-discord");
const session = require("express-session");
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(async(user, done) => {
await (await client.guilds.cache.get("guildID").members.fetch(user.id)).roles.add("roleID")
await (await client.guilds.cache.get("guildID").members.fetch(user.id)).setNickname(PHP DATA TO HERE)
return done(null, user)
});
You can do it via AJAX as Lajos suggested, also you can assign it to the JS variable from PHP at the moment of page rendering. All depends on your needs, so just choose the solution which is better for your case.
In your current code instead of echoing JSON, assign it to the JS variable.
echo "<script>let myJsonInJs = $myJson</script>";
so later you can use that variable somehow in your JS, i.e.:
<script>
console.log(myJsonInJs)
</script>
You will need to send an AJAX (Asynchronous Javascript And XML) request to your server-side. Let's implement a function for this purpose:
function sendRequest(type, url, callback, async, params) {
if (async !== false) async = true;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = callback;
xhttp.open(type, url, async);
xhttp.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");
xhttp.send(params);
}
You can call it like:
sendRequest("POST", "yoururl", function() {
if (this.readyState === 4) {
console.log(JSON.parse(this.responseText));
}
}, true, "username=Test");
Change yoururl to the proper location of your PHP script and pass some parameters if needed.
EDIT
If you are inside the NodeJS environment and you are able to send the request at this level, then you can use fetch, as Endless has pointed out in the comment section.
I am working on a management system, currently creating the POST requests for the api. I need the values of the request's body to post a new city in the database. The values are used in the stored procedure as parameters. Instead of the key's values which I entered, I am getting an "undefined" value, sometimes a "[object Object]".
I am using a MySQL server, hosted in the cloud by Google's services. Backend is made with Node.js, routing with Express. None of my attempts to fix the bug worked for me.
What I've tried so far:
-Parsing each key's value .toString() and JSON.stingfify() from the body
-Converting the body to Json/string, then back to a javascript object
-Getting the response's requests's body (res.req.body)
-Getting the body's response values in an array, then pushing the next element after it has been passed as a parameter to the stored procedure
-Using the 'request' npm extension to put the values I need when calling the POST method.
-Changed the values to be stored in the URL' parameters instead of the body.
-Sent the body's values as form-data, JSON file, HTML page
Controller method in cityController.js:
exports.city_post = (req, res, next)=>{
poolDb.getConnection(function (err, connection){
if(!err) {
const sql = 'CALL createNewCity(?,?)';
var zipReq = req.params.zip;
var nameReq = req.params.name;
var reqBody = JSON.stringify(req.res.body);
connection.query(sql,[zipReq,nameReq], (err,rows)=>{
if(!err){
return res.status(201).json({Message: 'City with name: '+nameReq+' and zip code: '+zipReq+' created successfully\n', rows});
}
else{
return res.status(404).json({errorMessage: err})
}
});
}
else{
return res.status(500).json({errorMessage: "server error: "+this.err});
}
console.log("\nZip Code: "+ zipReq +"\nName: " + nameReq); //for testing
console.log("\nrequest body: " + reqBody); //for testing
});
}
City route:
const express = require('express');
const router = express.Router();
const CityController = require('../controllers/cityController.js');
router.get('/', CityController.city_getAll);
router.get('/:cityzip', CityController.city_getbyzip);
router.post('/add', CityController.city_post);
...
module.exports = router;
Expected: Posting a new field in table city, status code (201).
Actual: Status code (404), no new insertion in the DB. body, req.body.zip & req.body.name are of value "undefined".
Screenshots:
-Terminal output: https://imgur.com/a/brqKZlP
-Postman request: https://imgur.com/a/ZfFcX8Z
Express doesn't parse post body by default (for some reason). You can try popular body-parser npm package, or collect the raw body data and parse from a string yourself if you don't want to add a whole new package. Here as express app:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
var json = JSON.parse(req.rawBody); // assuming valid json. ideally check content-type first
next();
});
});
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
Newbie in node and express
I am taking user input from html-form and trying to append or push it in a .json file.
I have used jsonfile npm-package but it is not coming in a array format of json
code for appending-
var express = require('express');
var app = express();
//jade --> ejs -->html
app.engine('html', require('ejs').renderFile);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
var jsonfile = require('jsonfile');
var file = './userdata.json'
//trying to write via form to json
app.post('/gettingdata', function(req, res) {
var user_id = req.body.usrid;
var token = req.body.usrphone;
var geo = req.body.usrdata;
//start writing
var obj = { name: user_id , phone: token, adress: geo }
jsonfile.writeFileSync(file, obj, {flag: 'a'});
//default
//res.send(user_id + ' ' + token + ' ' + geo);
});
html -
<body>
<form action="/gettingdata" method="post">
Name:<input type="text" name="usrid" /><br>
Phone:<input type="text" name="usrphone" /><br>
RData:<input type=="text" name="usrdata" /><br>
<input type="submit" value="Submit" >
</form>
</body>
json appearing as-
{"name":"name1","phone":"8989898989","adress":"random1"}
{"name":"name1","phone":"767656568","adress":"randomdata1"}
{"name":"name1","phone":"767656568","adress":"randomdata1"}
there are no commas appearing between objects and no square brackets. I need them to be able to make parsing possible, so that I can dynamically edit and delete data from my front-end later.
Suggest any link,method or npm package to do so.If question repeated share the link of that too
I will expand on Shil's answer with some code:
// 1. Read the existing file
fs.readFile(file, (err, data) => {
if (err && err.code === "ENOENT") {
// But the file might not yet exist. If so, just write the object and bail
return fs.writeFile(file, JSON.stringify([obj]), error => console.error);
}
else if (err) {
// Some other error
console.error(err);
}
// 2. Otherwise, get its JSON content
else {
try {
const fileData = JSON.parse(data);
// 3. Append the object you want
fileData.push(obj);
//4. Write the file back out
return fs.writeFile(file, JSON.stringify(fileData), error => console.error)
} catch(exception) {
console.error(exception);
}
}
});
This is just a quick, illustrative example: it is inefficient as the file grows as it has to read and write the entire file every single time.
Note that this will create a file which contains an array of objects, which is how you make lists of objects in JSON. So your final output will look like this:
[
{"name":"name1","phone":"8989898989","adress":"random1"},
{"name":"name1","phone":"767656568","adress":"randomdata1"},
{"name":"name1","phone":"767656568","adress":"randomdata1"}
]
Seems the library u are using can't do that thing. In both methods I find this:
var str = JSON.stringify(obj, options.replacer, spaces) + '\n'
//not sure if fs.writeFileSync returns anything, but just in case
return fs.writeFileSync(file, str, options)
where it writes into file the string you have just passed into the function, so it doesn't evaluate what it is already written into the file. So it will write one json every time you call the function. It won't continue to add elements to the existing json. You should do a custom function to do it.
You could do this:
retrive what it's already in the file
parse into json
append the json object you want to add
stringify the result and save it into the file replacing what was writing first.
edit:
sources:
writeFile /
writeFileSync
I'm using nodejs with node-http-proxy along with harmon. I am using harmon to rewrite the proxied response to include a javascript file and a css file. When I set the target of the proxy to be http://nodejs.org or anything other than localhost, I receive a 301 or 302 redirect. The script is rewriting the 301 response instead of the fully proxied response. How can I use harmon to rewrite the end response instead of the 302 response?
Here is the example of the script I am running from the harmon example folder:
var http = require('http');
var connect = require('connect');
var httpProxy = require('http-proxy');
var selects = [];
var simpleselect = {};
//<img id="logo" src="/images/logo.svg" alt="node.js">
simpleselect.query = 'img';
simpleselect.func = function (node) {
//Create a read/write stream wit the outer option
//so we get the full tag and we can replace it
var stm = node.createStream({ "outer" : true });
//variable to hold all the info from the data events
var tag = '';
//collect all the data in the stream
stm.on('data', function(data) {
tag += data;
});
//When the read side of the stream has ended..
stm.on('end', function() {
//Print out the tag you can also parse it or regex if you want
process.stdout.write('tag: ' + tag + '\n');
process.stdout.write('end: ' + node.name + '\n');
//Now on the write side of the stream write some data using .end()
//N.B. if end isn't called it will just hang.
stm.end('<img id="logo" src="http://i.imgur.com/LKShxfc.gif" alt="node.js">');
});
}
selects.push(simpleselect);
//
// Basic Connect App
//
var app = connect();
var proxy = httpProxy.createProxyServer({
target: 'http://nodejs.org'
})
app.use(require('../')([], selects, true));
app.use(
function (req, res) {
proxy.web(req, res);
}
);
The problem is that a lot of sites are now redirecting HTTP to HTTPS.
nodejs.org is one of those.
I have updated the sample https://github.com/No9/harmon/blob/master/examples/doge.js to show how the http-proxy needs to be configured to deal with HTTPS.
If you still have problems with other arbitrary redirects please log an issue on harmon.
Thanks