I am trying to retrieve data from a html table and insert this in MySQL database. I am already able to do the reverse, which is retrieve the information from the database and display it in same table using ejs template. I can also insert raw/JSON data into MySQL, but I'm unable to extract the data from same table because I am unable to reference that table from the server side (the same way body parser does with form data).
I have searched the web, all tutorials just do an insert to database using json data, nobody is retrieving data first from html table.
With below code I can loop through table data using plain javascript.
var table = document.getElementById('vehiclesTB');
for (var i = 1; i < table.rows.length; i++) {
if (table.rows[i].cells.length) {
var vehicleTag = (table.rows[i].cells[0].textContent.trim());
}
}
How do I pass retrieve data from html table to my controller(server side)? I am unable to reference html table directly from my server file (app.js).
My app.js file:
var express = require('express')
, routes = require('./routes')
, controls = require('./routes/controls')
, http = require('http')
, path = require('path');
var app = express();
var mysql = require('mysql');
var bodyParser =require("body-parser");
var pool = mysql.createConnection({
connectionLimit: 100,
host: 'localhost',
database: 'vehicluster',
user: 'motor',
password: '',
debug: false
});
pool.connect();
// all environments
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.post('/vehicle', controls.vehicle);
//Middleware
app.listen(8080)
My controls.js file.
exports.vehicle = function(req, res){
var table = document.getElementById('vehiclesTB');//how to read this
table in ejs
for (var i = 1; i < table.rows.length; i++) {
if (table.rows[i].cells.length) {
var vehicleTag = (table.rows[i].cells[0].textContent.trim());
var vehicleMake = (table.rows[i].cells[1].textContent.trim());
var vehicleModel = (table.rows[i].cells[2].textContent.trim());
var price = (table.rows[i].cells[3].textContent.trim());
var quantity = (table.rows[i].cells[4].textContent.trim());
}
}
var sql = 'insert into Vehicle(make, model, price, quantity) values
(?,?,?,?,?)';
pool.query(sql,[vehicleMake, vehicleModel, price, quantity],
(err,data)=>{
if(err){
console.log(err);
return
}else{
console.log(data);
}
};
The HTML table is showing relevant item (table), place table data into mysql database. I can already retrieve to table:
<div style="overflow-x: auto;">
<table id="customers">
<tbody id="mytbody">
<tr>
<th>Make</th>
<th>Model</th>
<th>price</th>
<th>quantity</th>
</tr>
<tr>
<th>toyota</th>
<th>camry</th>
<th>200</th>
<th>5</th>
</tr>
<tr>
<th>honda</th>
<th>civic</th>
<th>400</th>
<th>7</th>
</tr>
</tbody>
</table>
</div>
I am getting errors as you would expect, getElementById is client side, null value etc, database is not updated. Most tutorials online show the reverse, which is to insert database values into html table, instead of the other way around. Any help with real table example/route will be appreciated.
If you need to have a client-side HTML table made available on the server, then you will need to add an ajax endpoint at the server and code to send the HTML data (see the axios library).
I am not sure of your use case as it seems the data at the client side should already be available at the server since you rendered it. It may not be in HTML, but the data should exist there. Unless of course you are getting the HTML table from another source (or perhaps this is just an exercise in HTML parsing??).
Here is an update to show how to use axios. Note though that you still need to investigate that library to learn how to handle errors or even if you need to do other things upon success.
In your front end:
var table = document.getElementById('vehiclesTB');
var postBody = [];
for (var i = 1; i < table.rows.length; i++) {
if (table.rows[i].cells.length) {
var vehicle = {
vehicleTag: (table.rows[i].cells[0].textContent.trim())
vehicleMake: (table.rows[i].cells[1].textContent.trim()),
vehicleModel: (table.rows[i].cells[2].textContent.trim()),
price: (table.rows[i].cells[3].textContent.trim()),
quantity: (table.rows[i].cells[4].textContent.trim())
}
postBody.push(vehicle);
}
}
axios({ // should add error handling as appropriate
method: 'post',
url: '/vehicle',
data: postBody
});
Then on your server side, modify your controls.js:
exports.vehicle = function(req, res) {
var table = req.body; // assumes you have used bodyparser middleware to parse JSON into an object
for (var i = 1; i < table.length; i++) {
var vehicle = table[i];
var sql = 'insert into Vehicle(make, model, price, quantity) values ( ? , ? , ? , ? , ? )';
pool.query(sql, [vehicle.vehicleMake, vehicle.vehicleModel, vehicle.price, vehicle.quantity],
(err, data) => {
if (err) {
console.log(err);
return
} else {
console.log(data);
}
});
}
};
Also, I would suggest you look at Array.forEach for looking over an array instead of the for loop method you are using (see MDN documentation)
Related
I am working on an assignment that required us to fetch data of newsfeeds from a MongoDB database using monk. And put them onto a webpage. I am planning to get the data needed in an array. But when I run this, it responses
newsList.find(...).toArray is not a function
I have searched for a solution for that for a while. And I can't really find one.
app.get('/newsfeed.html', function(req, res){
var db = req.db;
var newsList = db.get('newsList');
var newsArray = newsList.find({}, ['-_id', 'headline', 'date', 'content', '-comments']).toArray();
var response = "";
for (let i = 0; i < newsArray.length; i++){
response += newsArray[i];
}
res.send(response);
});
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!
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();
});
});
I'm teaching myself Nodejs and am trying to populate a page with a list of nearby businesses' opening and closing hours from Yelp's API. I created a POST route to my page in Express, calling the Yelp API using the Yelp Fusion client. I am able to gather an array of ids which must be used in another endpoint in order to fetch the hours of operation, however I keep receiving TOO_MANY_REQUESTS_PER_SECOND errors when do this, despite setting the limit in the request.
Server.js
var express = require("express");
var app = express();
var yelp = require("yelp-fusion");
var bodyParser = require("body-parser");
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
let client = yelp.client("API_HIDDEN");
app.get("/", function(req,res){
res.render("landing");
});
///Initial request made to obtain business ids
app.post("/", function(req, res){
client.search({
term: 'cafe',
location: 'Oakland',
limit: 20
}).then(response => {
var ids = [];
var businesses = response.jsonBody.businesses;
var idName = businesses.map(el => {
ids.push(el.id);
});
// request separate endpoint, passing ids from the ```ids```array
for(var x = 0; x < businesses.length; x++){
client.business(ids[x]).then(response => {
console.log(response.jsonBody.hours);
})}.
res.render("search");
}).catch(e => {
console.log(e);
});
})
app.listen(3000);
I have tried calling client.businesses[id] both inside and outside a for loop but this resulted in errors too. I am confused on the behaviour of this as I am only making 20 calls, far below the minimum, but also how to possibly pass the ids if not for an array as I have run out of ideas. Thank you in advance for your help.
Spread out the api calls over time.
var delay = 1.1 * 1000; // 1.1 seconds in milliseconds
for(var x = 0; x < businesses.length; x++){
setTimeout(function(i){
client.business(ids[i]).then(response => {
console.log(response.jsonBody.hours);
});
},delay*x,x);
}
I have a server with 3 databases with identical tables.
DB1, DB2 and DB3.
When I work with a database I use:
app.js
var cnxDB= require('./routes/cnxDB');
app.post('/userSave', cnxDB.userSave);
cnxDB.js:
var sql = require('mssql');
var qs = require('querystring');
var colors = require('colors');
var config = {user: 'user',password: 'pass',server: '127.0.0.1',database: nameDB',
options: {
encrypt: false
}
};
sql.connect(config, function(err) {
//Connection
});
exports.userSave = function(req, res) {
//response
};
When initializing the application immediately makes the connection to the database.
I need to know how you can do to choose the database.
app.post('/selectBD', function(req, res){
var body = req.body; // accede a la informaciĆ³n enviada por el socket
console.log(body);
if(body.cnx == 1)
{
var cnx = require('./routes/bdUno');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 2)
{
var cnx = require('./routes/bdDos');
app.get('/yuri', cnx.findall);
}
if(body.cnx == 3)
{
var cnx = require('./routes/bdTres');
app.get('/yuri', cnx.findall);
}
res.status(200).json("Ok");
});
Thank you.
In cnxDB.js set up 3 connections:
var connections = {
<dbname>: null,
<dbname>: null,
<dbname>: null
}
go to mssql and look at "Quick Example". It creates a connection and saves it in a variable. You'd want to do that 3 times for each db and save them in connections under the corresponding db name.
Then the functions you export from cnxDB.js should have a way to know which db you want them to use. By the looks of it you want to have some indication of what db needs to be used in the body of that request. You can use that to pick the db.