POST data passed from frontend JS to Nodejs/Expressjs is always undefined - javascript

I have a frontend JS script that takes text input from an HTML text box and sends it to an expressjs server. The body of the POST request, though, is always undefined, or depending on how I tweak things, returning as "{ }" if I view it via console.log( ). As I'm new to this, I can't seem to see what's going wrong.
Front end js:
async function submitCity(){
let x = document.getElementById("wg_input").value;
console.log("Successfully captured city name:", x);
let toWeather = JSON.stringify(x);
console.log("Input data successfully converted to JSON string:", toWeather);
const options = {
method: 'POST',
mode: 'cors',
headers: {'Content-Type': 'text/plain'},
body: toWeather
}
fetch('http://localhost:3000', options)
.then(res => console.log(res))
.catch(error => console.log(error))
}
Backend:
// Dependencies
const express = require('express');
const bp = require("body-parser");
const request = require("request");
const jimp = require('jimp');
const cors = require('cors');
const wgServer = express();
const port = 3000;
// Dotenv package
require("dotenv").config();
// OpenWeatherMap API_KEY
const apiKey = `${process.env.API_KEY}`;
// Basic server initialization
wgServer.use(cors())
wgServer.use(bp.json())
wgServer.use(bp.urlencoded({ extended: true }))
wgServer.listen(port, function() {
console.log(`Example app listening on port ${port}!`)
});
wgServer.post('/', async function (req, res) {
res.set('Content-Type', 'text/plain');
console.log(req.body)
res.send('Hello World');
//const data = await req.body;
// let jsonData = JSON.stringify(req.body);
// res.status(201);
//res.json();
});
The returned data is supposed to be a string of about 15 characters, give or take a few (a city and state). I thank you in advance.

Related

can anyone help me for the issue of Javascript post call is sending null value to mongoDB?

I am a beginner in JS, NodeJS, and MongoDB. I created a quiz website to practice my coding skills and I am facing the issue while sending the username (string) and total marks (int) to mongo DB via Post method. it is sending null values only. When I hardcode the values in the app.js file, it inserts the data correctly to DB correctly, but via JS, there are only null values. adding code below:
index.js (username is string and marks is number)
var obj = {
name:username,
total:marks
}
console.log(JSON.stringify(obj))
fetch('/index', {method:'POST', body:JSON.stringify(obj)});
app.js
const express = require('express')
const app = express()
app.use(express.urlencoded());
app.use(express.json());
const path = require('path')
const port = process.env.port || 80
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/dataDB', {useNewUrlParser: true})
// const dataSchema = new mongoose.Schema({total:Number});
const dataSchema = new mongoose.Schema({
name:String,
total:Number
});
const data = mongoose.model('data',dataSchema);
app.use('/static', express.static('static'))
app.set('view engine','pug')
app.set('views', path.join(__dirname,'views'))
app.get('/',(req,res) => {
const params = {}
res.status(200).render('index.pug',params);
});
app.post('/index',(request,res) => {
console.log(JSON.stringify(request.body)); //---giving null
console.log(request.body); //---giving null
console.log(JSON.stringify(request.body.name)); //---giving null
console.log(request.body.name); //---giving null
var userData = new data(request.body)
userData.save().then(()=>{
console.log("data saved into DB")
}).catch(()=>{
console.log("data not saved")
});
});
app.listen(port, () => {
console.log(`application has been started at ${port}`)
})
Try setting the header, while sending the request:
fetch('/index',
{method:'POST', headers: {
'Content-Type': 'application/json',
},
body:JSON.stringify(obj)});

node express return request body empty by using API fetch POST

Learning nodejs and trying to post a form from HTML (with image upload) to nodejs (express) but the request.body returning empty object.
Tried few solutions on this site but no one is working.
Here is my code for creating a dynamic form. (HTML)
function show(data) {
const d = data.temp_form;
let content = ''
// console.log(d)
d.forEach((item) => {
if (item === 'image_backup' || item === 'image_banner') {
content += `<label for='${item}'>${item}</label><input name='${item}' type='file' id='${item}' value=''><br/>`
}else{
content += `<label for='${item}'>${item}</label><input name='${item}' type='text' id='${item}' value=''><br/>`
}
})
content += ` <input type="submit" id="handle_submit">`
getFormContianer.innerHTML = content
}
Code handling form submit
async function handleForm(e) {
e.preventDefault();
let dataForm = new FormData(e.target)
let obj = {}
dataForm.forEach((value, key) => {
obj[key] = value
if( typeof value === 'object'){
console.log(value.name)
obj[key] = value.name
}
});
let data = JSON.stringify(obj);
await fetch(file_api, {
method: 'POST',
body: data
}).then((res)=>{
return res.json();
}).then((data)=>{
console.log('api err: '+data);
}).catch((err) =>{
console.log('api err: '+ err)
})
}
Then, in my nodejs
const express = require('express');
const cors = require('cors');
const config = require('./config')
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
const app = express()
const templates = require('./routes/templates-routes');
const files = require('./routes/files-routes');
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());
app.use(express.static('public'))
app.use('/api', templates.routes);
app.use('/create', files.routes);
app.listen(config.port, () => {
console.log(`Example app listening at http://localhost:${config.port}`)
})
and in the route.js
const express = require('express');
const router = express.Router();
const {replaceValue } = require('../controllers/filesController');
router.post('/file', replaceValue);
module.exports={
routes: router
}
for the fileController.js
const replaceValue = (request, response) =>{
console.log(request.body)
response.send(request.body)}
Hope that can get some comment for you, thank you so much!
let data = JSON.stringify(obj);
await fetch(file_api, {
method: 'POST',
body: data
You are passing a string to body and haven't specified a Content-Type header so fetch will generate a Content-Type: text/plain header.
Since plain text isn't JSON, the JSON parsing middleware you have set up in Express won't process it.
await fetch(file_api, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: data
Note that this will make it a preflighted request, so make sure you follow the instructions for the CORS module to support that.

What does it mean by this async Javascript server app error?

I was setting a weather app website that is connected to another site using a server, and asynchronous javascript was used, but after trying to run the code, an error reading "uncaught syntax error: unexpected end of input" in the last line in the app file...I don't understand what it means and therefore I don't know how to solve it
here's my app file code
/* Global Variables */
const apiKey = "726f360f99f8ed5ce834f19b2f632fd3"
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = +d.getMonth()+1+'.'+ d.getDate()+'.'+ d.getFullYear();
const gen = document.querySelector("#generate");
gen.addEventListener("click", async() =>{
const Zcode = document.querySelector("#zip").value;
const feel = document.querySelector("#feelings").value;
try {
getTemp()
.then(temp =>{
const object = {
date: newDate,
temp: temp,
}
return DealingWithServer()
})
.then(data =>{
UpdateSite(data)
})
}catch(error){
console.log(error);
}
});
async function getTemp (){
const res = await fetch (`https://api.openweathermap.org/data/2.5/weather=?zip=${zipCode}&appid=${apiKey}&units=metric`);
const data= await res.json;
const temp = data.main.temp
return temp
}
async function DealingWithServer (){
await fetch('/recieve', {
method: "POST",
credentials: "same-origin",
headers: {"Content-Type": "application/json"},
body:JSON.stringfy({
date: newDate,
temp: temp,
feel: feel
})
});
const Sres = await fetch('/get', {credentials: "same-origin"});
const Sdata = await Sres.json()
return (Sdata);
}
function UpdateSite (data)
and my server file code
// Setup empty JS object to act as endpoint for all routes
projectData = {};
const port = 3000;
// Require Express to run server and routes
const express= require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
// Start up an instance of app
const app=express()
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
app.use(cors())
// Initialize the main project folder
app.use(express.static('website'));
app.get("/get",(req, res) => {
res.send(projectData)
})
app.post("/recieve", (req, res) => {
projectData =req.body
res.status(200)
})
// Setup Server
app.listen(3000,() =>{
console.log("Server running");
})
It looks to me like you've not finished your UpdateSite function at the bottom. It should read something like this:
function UpdateSite (data) {
// Do things to update the site
}
Since there is no function definition, the input (JavaScript code in this case) has ended unexpectedly - i.e. the parser was not expecting the input to end with function UpdateSite (data)

Unable to retrieve Req.Query on Express

I am currently trying to retrieve my Query String data to use it as a parameter for my OpenWeather API call later on.
I am having issues retrieving the Query String that is being sent to my server although it appears on the URL request. I keep getting "undefined" when I try to console.log the req.query on my server. I'm guessing that I didn't parse the Query String data properly which causes it to be "undefined". So looking at the picture i've attached, using the city=Tokyo as my req.query.
I've pasted the client-side, server-side, and screenshots of my web app.
Any ideas?
P.S. I've just started learning, so I'm sorry in advance
**Client-Side JS file**
let cityForm = document.querySelector('#cityName');
let city = document.querySelector('#city');
let button = document.querySelector('#btn');
button.addEventListener('click', getData);
async function getData () {
console.log('Value entered '+ city.value);
let options = {
method: "POST",
headers: {
'Content-Type': 'application/text'
},
body: JSON.stringify(city.value)
};
console.log('value being sent ' + options.body);
let fetchin = await fetch('/', options); // making the post request here to the server
let rezponse = await fetchin.json();
console.log(rezponse);
};
**Server-Side JS file**
let express = require('express');
let app = express();
let bodyParser = require('body-parser');
let fetch = require('node-fetch');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.set('view engine','ejs');
app.use(express.static(__dirname + '/views'));
app.get('/', (req, res) =>{
res.render('home');
});
app.post('/', async (req, res)=>{
console.log('The value of the query '+ req.query);
// let user = await fetch('http://api.openweathermap.org/data/2.5/weather?q=' + req.query.city + '&appid=APIKEY');
// let item = await user.json();
// res.json(user);
// console.log(item);
//Idea is to use the req.query coming from the client-side to use for
in the API call to OpenWeather, get the details from the API and send it back
});
app.listen(4000, ()=>{
console.log('Post has been called');
});
you are missing the search params that are required to be added to the url, so that you can access them on the server
//client side
let options = {
method: "POST",
headers: {
'Content-Type': 'application/text'
}
};
let url = new URL('/');
url.searchParams.set('q', 'Tokyo')
let fetchin = await fetch(url, options);
On the server-side, you are trying to log the req.query when you post to /.
app.post('/', async (req, res)=>{
console.log('The value of the query '+ req.query);
However, on the client-side, you are posting to / without any query params.
let fetchin = await fetch('/', options);
You could append the query params to / like shown below.
let fetchin = await fetch(`/city=${city.value}`, options);
OR
Since you are already posting the city.value as the post body from the client side, on the server side you can access it using req.body.
app.post('/', async (req, res)=>{
console.log('The value of req body '+ req.body);

Get value from client side script and override server side script

Below are my server side and client side JavaScript files. I have hard coded queryObject in server side script I can display the body in client-side.
The problem is how to get value from client side for queryObject variable in server side and override the existing values.
In short, current program converts USD to GBP as I hard-coded it. I want a way to access queryObject from client side and give my own values.
//=====================Server Side Script========================//
var request = require('request');
const path = require("path");
const express = require("express");
const app = express();
// const hbs = require("hbs");
const port = process.env.PORT || 3000;
const pathPublic = path.join(__dirname, "../public");
const pathView = path.join(__dirname, "../templates/views");
app.set("view engine", "hbs");
app.set("views", pathView);
app.use(express.static(pathPublic));
app.get("", (req, res) => {
res.render("home", {
title: "Currency Converter"
});
});
app.get("/currency", (req, res) => {
const uri = "https://currency-exchange.p.rapidapi.com/exchange?",
headers={
'x-rapidapi-host': 'currency-exchange.p.rapidapi.com',
'x-rapidapi-key': 'b13c4f3d67msh8143a7f1298de7bp1e8586jsn4453f885a4e7'
}
const queryObject = {
q: 1,
from: 'USD',
to: 'GBP'
};
request({
url:uri,
qs:queryObject,
headers: headers
},
function (error, response, body) {
if (error) {
console.log('error:', error); // Print the error if one occurred
} else if(response && body) {
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
res.json({'body': body}); // Print JSON response.
}
})
});
app.listen(port, () => {
console.log("Server is running on port " + port);
});
//=====================Client Side Script========================//
const currency = document.querySelector("#currency");
const text1= document.querySelector(".text1");
const text2= document.querySelector(".text2");
const text3= document.querySelector(".text3");
const Form = document.querySelector("form");
function refreshPage() {
window.location.reload();
}
Form.addEventListener("submit", e => {
e.preventDefault();
fetch("http://localhost:3000/currency").then(response => {
response.json().then(data => {
if (data.error) {
console.log(data.error);
} else {
currency.textContent = data.body;
}
});
});
SOLUTION:
In order to modify any values in server, you have to send appropriate HTTP method (eg: POST) with appropriate data in it. And let the server handle the request to change the content of object to make an API call from there.
I made some changes in your code for demonstration and install 'cors', 'body-parser' module and other missing modules to make it run.
HTML:
<!DOCTYPE html>
<html>
<body>
<div id="currencyType">
<select id="fromCurrency">
<option value="USD">USD</option>
<option value="GBP">GBP</option>
</select>
<select id="toCurrency">
<option value="USD">USD</option>
<option value="GBP">GBP</option>
</select>
</div>
<button type="button" id="getCurrency">Get Currency</button>
<div id="currency" name="currency" type="text"></div>
<script>
const currency = document.querySelector("#currency");
const btn = document.getElementById("getCurrency");
function refreshPage() {
window.location.reload();
}
btn.addEventListener("click", e => {
var fromCurrency = document.getElementById("fromCurrency");
fromCurrency = fromCurrency.options[fromCurrency.selectedIndex].value;
var toCurrency = document.getElementById("toCurrency");
toCurrency = toCurrency.options[toCurrency.selectedIndex].value;
var data = {
fromCurrency: fromCurrency,
toCurrency: toCurrency
};
// calls the API with POST method with data in it
fetch("http://localhost:3000/currency", {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}).then(response => {
response.json().then(data => {
if (data.error) {
console.log(data.error);
} else {
currency.textContent = "1 " + fromCurrency + " = " + data.body + " " + toCurrency;
}
});
});
});
</script>
</body>
</html>
NodeJS:
var request = require('request');
const path = require("path");
const express = require("express");
const app = express();
var cors = require('cors')
// const hbs = require("hbs");
var bodyParser = require('body-parser');
const port = process.env.PORT || 3000;
const pathPublic = path.join(__dirname, "public");
const pathView = path.join(__dirname, "templates/views");
app.set("view engine", "hbs");
app.set("views", pathView);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(pathPublic));
app.use(cors())
app.get("", (req, res) => {
res.render("home", {
title: "Currency Converter"
});
});
app.post("/currency", (req, res) => {
console.log(req.body);
const uri = "https://currency-exchange.p.rapidapi.com/exchange?",
headers={
'x-rapidapi-host': 'currency-exchange.p.rapidapi.com',
'x-rapidapi-key': 'b13c4f3d67msh8143a7f1298de7bp1e8586jsn4453f885a4e7'
}
const queryObject = {
q: 1,
from: req.body.fromCurrency,
to: req.body.toCurrency
};
console.log(queryObject);
request({
url:uri,
qs:queryObject,
headers: headers
}, function (error, response, body) {
if (error) {
console.log('error:', error); // Print the error if one occurred
} else if(response && body) {
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
res.json({'body': body}); // Print JSON response.
}
})
});
app.listen(port, () => {
console.log("Server is running on port " + port);
});
Sample output:
You'll code in client-side to send a request to server-side containing the query object.
And on the server-side, you pick up your query object.
There are so many ways of doing this.
Using a GET request with parameters - On the server-side your query object will be available at res.query.params
Using a POST request - On the server side you will want to use the body-parser plugin for parsing your response body and hence, your data will be available at res.body
Read on body parser

Categories