I want to submit input value from HTML form to Node-js. Node-js should assign that value as an argument to a Solidity function. But the Error: TypeError: Cannot read property 'oinput' of undefined is shown. What should i do? Please help a beginner.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Alireza</title>
<body>
<form id="FORM" name="FORM" method="POST" action="http://127.0.0.1:1408">
<input id="Finput" name="oinput" value="Null" onclick="this.form.submit()"/>
</form>
<script>
document.forms[0].oinput.value=prompt("Type a thing: ","Here ...");
</script>
</body>
</html>
app.js:
var express=require('express');
var app=express();
var fs=require('fs');
var http = require('http');
var bodyParser=require('body-parser');
var Web3=require('web3');
var web3=new Web3('ws://127.0.0.1:8545');
var YerevanJSON="E:/Alireza/build/contracts/Yerevan.json";
var YerevanJS=JSON.parse(fs.readFileSync(YerevanJSON));
var YerevanABI=YerevanJS.abi;
var Yerevan=new web3.eth.Contract(YerevanABI, "0x1E6B6524e7da86bafa5ac948b38dA68e6841f0c7");
Yerevan.defaultAccount="0x152AfF6BBF98F2FF2EFAdA32E2ba85CC231cbA13";
app.post("/", function(q,r){
Yerevan.methods.eval(q.body.oinput).send({from:"0x33aa0ba26Dc247BA5d94545344c413949B746360"});
});
app.listen(1408, err=>{ console.log('ERROR')});
Solidity:
pragma solidity ^0.5.12;
contract Yerevan{
string public city;
function eval(string memory sense) public returns(string memory){
city=sense;
return city;
}
}
You have included body-parser on to the file but hasn't asked the app use it.
add below line
const bodyParser = require("body-parser");
// for parsing application/json
app.use(bodyParser.json());
//for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
You are using var, start using const and let instead.
Related
Basically I have a .json file, and I want to make a html page that someone can fill out a form, and the information in the form will change variables in the JSON file.
Example:
The json file (for example):
{“title”: “(variable)”}
then when the html form is submitted it will read (variable) as what was entered into the form.
It depends on what you have on the backend (Node, python, etc)
Welcome to Stackoverflow, seeing that you have NodeJS, you may want to establish some sort of communication from your back end to front end. Let's say you're using websockets. Here is how information would be passed:
userData.json:
{
name: "Mishra",
age: 89
}
server.js:
const app = express()
const server = app.listen(3000) // setup express server
const io = require('socket.io').listen(server); // using websockets
let userData = require('./userData.json');
// on socket connection event
io.on('connection', (socket) => {
socket.on('updateName', name => { // when updateName is called
userData.name = name // set JSON var to new name
})
}
// method to save JSON file goes here
myForm.html:
<head>
<script type="text/javascript" src="your/path/to/socket.io.js"></script>
<script>
var socket = io();
</script>
</head>
<body>
Set name:
<input type="text" id="nameField" name="fname"><br>
<input type="submit" value="Submit" id="submit">
<script>
document.getElementById("submit").onclick = () =>{
socket.emit("updateName", document.getElementById("nameField").value)
}
</script>
</body>
so I've been doin this bmiCalculator where I enter 2 numbers and these 2 numbers are calculated in my server and the answer is displayed but I have been facing troubling in receiving my output.when I click submit i am getting a list of all my files in the index of c but not the answer. Can someone please help me w this?
my HTML code
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>BMI calculator</h1>
<form action="/" method="post">
<input type="text" name="num1">
<input type="text" name="num2">
<input type="button" value="submit">
</form>
</body>
</html>
my js code
let express = require("express")
let bodyParser = require("body-parser")
let app = express()
app.use(bodyParser.urlencoded({extended: true}))
app.listen(3000,function(){
console.log("working")
})
app.get('/',function(request,respond){
respond.sendFile(__dirname+"/bmiCalculator.html")
})
app.post('/',function(req,res){
let num1 = Number(req.body.num1)
let num2 = Number(req.body.num2)
let result = num1/num2*num2
res.send(result)
})
According to Express res.send([body]) docs:
The body parameter can be a Buffer object, a String, an object, or an Array
You can't send a number by itself. So you could send a string using result.toString()
You should use <input type="submit" value="submit"> to submit the form.
E.g.
server.js:
let express = require('express');
let bodyParser = require('body-parser');
let app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(3000, function() {
console.log('working');
});
app.get('/', function(request, respond) {
respond.sendFile(__dirname + '/bmiCalculator.html');
});
app.post('/', function(req, res) {
console.log(req.body);
let num1 = Number(req.body.num1);
let num2 = Number(req.body.num2);
let result = (num1 / num2) * num2;
res.send(result.toString());
});
bmiCalculator.html:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>BMI calculator</h1>
<form action="/" method="post">
<input type="text" name="num1">
<input type="text" name="num2">
<input type="submit" value="submit">
</form>
</body>
</html>
Server logs after submit the form in client-side:
working
{ num1: '1', num2: '2' }
This is my function to fetch data:
let a = showbtn.addEventListener('click',function(){
list.innerHTML='';
fetch('http://localhost:3000/products')
.then ( response =>response.json())
.then( data => {
data.forEach( product => {
let li =document.createElement('li');
li.textContent=` ${product.id} - ${product.name} - $ ${product.price} `;
list.appendChild(li);
});
})
})
My App.js looks like this:
let express=require('express');
app=express();
//after completing index.html we set index.html as a home page like this by introducing public client folder:
app.use(express.static('public'));
productsArray=[];
//every products must have an id number:
let id=1;
app.use(express.json());
//showing all products:
app.get('/products',(req,res)=>{
res.send(productsArray);
})
//creating ptoducts(posts):
app.post('/products',(req,res)=>{
let newProduct=req.body;
newProduct.id=id;
id++;
productsArray.push(newProduct);
res.send('new product created by newProduct=req.body and added to array by push method: Array.push(newProduct)')
})
This is my HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>shop</title>
</head>
<body>
<h1>shop</h1>
<h2>show all products</h2>
<button class="show-products">show</button>
<!-- //everyl ist item is a separate product -->
<ul class="product-list"></ul>
<!-- //.................................................................... -->
<h2>add product</h2>
<form class="add-product-form">
<p>
<label for="add-product-name">
product:
</label>
<input id="add-product-name" type="text" >
</p>
<p>
<label for="add-product-price">
price:
</label>
<input id="add-product-price" type="text" >
</p>
<button>add</button>
</form>
<script src="js/script.js"></script>
</body>
</html>
The problem is that when i open chrome on localhost:3000 and type something in the field of products and price after that i click show button but i get this result something like this:
1 - undefined - $ undefined
the first one is it's id and the second is product name but is undefined and price as well. I think something is wrong with value but i can't solve this problem.
Thank you in advance.
When handling POST bodies in express you need to user body-parser
http://expressjs.com/en/resources/middleware/body-parser.html
npm install body-parser
var bodyParser = require('body-parser')
Code from the docs
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
in the js file remove the semicolon and replace it with comma
I am trying to create a back end for my front-end web page using Node.JS. The web page is using google translate API and translates the users word. At the moment I am able to get it to work when I hard code the word and the language to/from. What i am trying to do is retrieve the word they input and the language they want to translate to.
Code from front end
function translateWord() {
var url = 'http://localhost:8085';
var endpoint = '/translate';
var fromLang = document.getElementById("fromLang").value;
var toLang = document.getElementById("toLang").value;
var word = document.getElementById("wordInput").value;
var payload = {"word": word, "from": fromLang, "to": toLang};
console.log(payload);
var http = new XMLHttpRequest();
http.open("POST", url+endpoint, true);
http.setRequestHeader("Content-type", "application/json");
http.onreadystatechange = function() {
var DONE = 4; // 4 means the request is done.
var OK = 200; // 200 means a successful return.
if (http.readyState == DONE && http.status == OK && http.responseText) {
var reply = http.responseText;
document.getElementById("mainBody").innerHTML = reply;
}
};
var params = JSON.stringify(payload);
// Send request
http.send(params);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Translation Demo</title>
<link rel="stylesheet" href="css/main.css" type="text/css">
</head>
<body>
<script src="js/main.js"></script>
<div>
<h1> Translation Demo </h1>
<p>Word:<input id="wordInput" type="text"></p>
<p>From:
<select id="fromLang">
<option value="en" selected>English</option>
<option value="fr">French</option>
<option value="es">Spanish</option>
<option value="ru">Russian</option>
</select>
To:
<select id="toLang">
<option value="en">English</option>
<option value="fr" selected>French</option>
<option value="es">Spanish</option>
<option value="ru">Russian</option>
</select>
</p>
<button onclick="translateWord()">Translate</button>
<p id="mainBody">Translation here.</p>
</div>
</body>
</html>
This is the back end I am having trouble with (this part works because its hard coded).
var express = require('express');
var router = express.Router();
var cors= require('cors');
router.use(cors());
router.post('/translate', function(req, res)
{
var payload = req.body;
var word = "hello";
var json = { from: 'en', to: 'fr' };
const translate = require('google-translate-api');
translate(word, json).then(function (resolve, reject){res.send(resolve.text.toString());});
});
module.exports = router;
To be able to grab the word and language, I tried doing something along the lines of this. Also I have it going to port 8085 so that's not the problem.
var payload = req.body;
var word = req[word];
var from = req[from];
var to = req[to];
var json = { from: 'from', to: 'to' };
When i try doing it this way i receive this error.
(node:6892) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property 'length' of undefined
Could someone point me in the right direction as to what I am doing wrong? I have been trying to solve this for awhile and haven't been able to.
By default, ExpressJS won't be able to parse JSON post data. To solve this, you can use the body-parser module.
Install it:
npm i -S body-parser
And use it like so in your code:
var express = require('express');
var bodyParser = require('body-parser'); // <----------------------------
var jsonParser = bodyParser.json(); // <----------------------------
var router = express.Router();
var cors= require('cors');
router.use(cors());
router.post('/translate', jsonParser, function (req, res) // <-----------
{
/* ... */
});
module.exports = router;
Then, inside that function, you'll be able to access your data:
var word = req.body.word;
var json = {
from: req.body.from,
to: req.body.to
};
How can I get the user inputs from index.html, process in node and output the result back into the index.html? Instead of outputting - as currently does - to a new page.
Form file
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', function(req, res){
res.sendFile('index.html', { root: __dirname});
app.post('/mess', function(req, res){ //means same dir
var userNum1 = req.body.num1;
var userNum2 = req.body.num1;
var answer = parseInt (userNum1) + parseInt (userNum2);
res.send ('The answer is ' + answer);
});
app.listen(80);
index.html
<!DOCTYPE html>
<html>
<head>
<title>Forms></title>
</head>
<body>
<form action="mess" method="post">
<p>Enter a number:</p>
<input type="text" name="num1" placeholder="..." />
<br>
<p>Enter a number:</p>
<input type="text" name="num2" placeholder="..." />
<br>
<button type="submit">Submit</button>
<br>
</form>
</body>
</html>
Probably the easiest way is to use ejs.
First npm install ejs. Then add this to your Express app code:
app.set('view engine', 'ejs');
// this allows you to render .html files as templates in addition to .ejs
app.engine('html', require('ejs').renderFile);
In your route handler you just do something like:
res.render('form', { answer: 'foo' });
and then your template (e.g. ./views/form.html) would look like:
<html>
<p> The answer is <%= answer %> </p>
</html>
An alternative to the EJS is to use socket.io. You can attach an event handler to each entry, or to the submit button and then use socket.io to send it from client to server, process it and have it sent back. Then you page can update on receiving the data from the server.