Passing data from Client to Server - javascript

In my code I want to pass an id from client to server.
I am trying to use fetch setting the Content-Type to Application/json but it looks like we have some problems (I analized the request and it doesn't create the body).
Is there a simply way to pass data from client to server?
{#each accounts}}
<form action="/users/chat" method="POST">
<div class="form-group">
<p>{{#index}}</p>
<label for="name" value={{username}}>{{username}}</label>
</div>
<div class="form-group">
<label for="name">{{email}}</label>
</div>
<button class="myButton" id="{{#index}}">chat</button>
</form>
{{else}}
<p>No account</p>
{{/each}}
<script>
const buttons = document.getElementsByClassName('myButton');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function(e) {
let ident=this.id;
console.log(ident);
console.log('button was clicked');
fetch("/myurl",{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify({id : ident})
})
}
</script>

Here is the code of the server:
var express = require('express');
var router = express.Router();
var app = express();
var bcrypt = require('bcryptjs');
const db = require('../config/database');
const Account = require('../models/Account');
const chat = require('../models/chat');
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
var passport = require('passport');
LocalStrategy = require('passport-local').Strategy;
const {ensureAuthenticated}=require('../config/auth');
app.use(express.urlencoded());
app.use(express.json());
//Socket
const PORTS = process.env.PORT || 7001;
var client = require('socket.io').listen((PORTS, console.log`SOCKET started on port ${PORTS}`)).sockets;
var password;
var username;
var accounts;
//Register
router.get('/register', function(req,res){
res.render('register');
});
//CHAT
router.get('/chat', ensureAuthenticated, (req,res)=>{
console.log(request.body.user.id);
res.render('chat');
});
module.exports=router;

Having checked carefully, this line here in your request from client is the cause fetch("/myurl",{ ...
If you see the guide at MDN, the usage is fetch('http://example.com/movies.json'). Fetch API expects complete url/uri along with the protocol (http, https) etc.
So your request should be like:
fetch("http://yourdomain.com", { ...

Related

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

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.

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.

Cant find the problem an express server problem

i have an express server which has the code:
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Dependencies */
const bodyParser = require('body-parser');
/* 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
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('website'));
const port = 8000;
// Setup Server
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
app.get('/all', sendData);
function sendData (req, res) {
res.send(projectData);
};
app.post('/all', receiveData);
function receiveData (req, res) {
projectData.temp = req.body.temp;
projectData.date = req.body.date;
projectData.ures = req.body.ures;
res.send(projectData);
console.log(projectData);
}
so simply i am making a weather journal app which receives data from an API and shows it to the user and this is the index look like:
so basically the user is going to write the zip code and feelings and when clicking on the button generate the entry should contain the information like this
but when the user click the button generate this shows and the user have to click it again in order to show the information like the top picture:
and this is the JavaScript code for the client-side:
/* Global Variables */
let baseURLz = 'http://api.openweathermap.org/data/2.5/weather?zip=';
let baseURLa = '&appid=';
const apiKey = '8e017daef09d7f784c8595696bdcb587';
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = d.getMonth()+'.'+ d.getDate()+'.'+ d.getFullYear();
document.getElementById('generate').addEventListener('click', performAction);
function performAction(e){
const zipcode = document.getElementById('zip').value;
const ures = document.getElementById('feelings').value;
getWeather(baseURLz, zipcode, baseURLa, apiKey)
.then(function(data){
console.log(data);
postData('/all', {temp: data.main.temp, date: newDate, ures: ures});
})
.then(
updateUI()
)
}
const getWeather = async (baseURLz, zipcode, baseURLa, apikey)=>{
const res = await fetch(baseURLz+zipcode+baseURLa+apikey+'&units = imperial')
try {
const data = await res.json();
console.log(data)
return data;
} catch(error) {
console.log("error", error);
// appropriately handle the error
}
}
const postData = async ( url = '', data = {})=>{
const res = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await res.json();
return newData;
}catch(error) {
console.log("error", error);
}
};
const updateUI = async () => {
const req = await fetch('/all');
try{
const allData = await req.json();
document.getElementById('date').innerHTML = 'Date: '+allData.date;
document.getElementById('temp').innerHTML = 'Temperature: '+allData.temp+'°F';
document.getElementById('content').innerHTML = 'Feelings: '+allData.ures;
}catch(error){
console.log("error", error);
}
}
and this is the html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weather Journal</title>
<link href="https://fonts.googleapis.com/css?family=Oswald:400,600,700|Ranga:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id = "app">
<div class ="holder headline">
Weather Journal App
</div>
<div class ="holder zip">
<label for="zip">Enter Zipcode here</label>
<input type="text" id="zip" placeholder="enter zip code here">
</div>
<div class ="holder feel">
<label for="feelings">How are you feeling today?</label>
<textarea class= "myInput" id="feelings" placeholder="Enter your feelings here" rows="9" cols="50"></textarea>
<button id="generate" type = "submit"> Generate </button>
</div>
<div class ="holder entry">
<div class = "title">Most Recent Entry</div>
<div id = "entryHolder">
<div id = "date"></div>
<div id = "temp"></div>
<div id = "content"></div>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
please i want to figure out where is the problem causing this to happen.

req.files always returns undefined with express-fileupload and body-parser

I am working on an assignment where I am to upload a file to a NodeJs server. Every time I hit the POST request on the server, req.files always returns undefined and I am not sure why. I am assuming that this has to do with what I am sending in the body of the request, but I guess I am not sure what exactly I need to send. I've read that body-parser only works with JSON objects, but even with that, the server still returns undefined. Any suggestions?
Here is the relevant code for both the client, server, and database files that I am working with:
admin.html (body):
<div style="display: none; margin-bottom: 6%;" id="part2B">
<label for="fileSelect2">Step 2: Upload a new image: </label>
<input type="file" id="fileSelect2" name="uploadFile2" value="" accept="image/*" onchange="fileSelected(event)">
</div>
admin.html (script):
function fileLoaded(event) {
var image = new Image();
image.onload = imageLoaded;
image.src = event.target.result;
let data = document.getElementById("fileSelect2").files[0]
fetchThemes().
then(tableOfContents => {
for (let theme of tableOfContents){
if (theme['name'] == document.getElementById("selectThemeInput").value){
fetch(host+'/image/:'+theme['id'], {
mode: 'cors',
method: 'POST',
body: JSON.stringify(data)
})
}
}
})
}
server.js:
// dependencies
const fileUpload = require('express-fileupload')
const bodyParser = require('body-parser')
const express = require('express');
const url = require('url');
var cors = require('cors');
const db = require('./db-001.js');
//create the server
const app = express();
const port = 3002;
// parse application/json
app.use(bodyParser.json())
app.use(cors())
app.use(fileUpload())
app.post('/image/:themeId', (request, response) => {
console.log(request.files)
let imageFile = request.files.image;
db.saveImage(request.params.themeId)
.then(image => {imageFile.mv('./data/' + image.name);})})
You need to encode your data as "multipart/form-data" instead of "json".
Quick example:
const fileInput = document.querySelector('#your-file-input') ;
const formData = new FormData();
formData.append('file', fileInput.files[0]);
const options = {
method: 'POST',
body: formData,
};

Error in the url passed when I connect to a weather api

This is my first app doing it with node.js and express. This is a basic app where I connect to an external API to show temperature and take a user input "city and feeling" and show it to the UI. I can't get the URL right. I don't know why.
I ran the app and entered data in the city and feeling text area, I debugged the app.js file and found that when it tries to fetch the URL I'm passing its data it gives the error "400 bad requests". What am I doing wrong?
the server.js
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
//body-parser as the middle ware to the express to handle HTTP POST
const bodyParser = require('body-parser');
//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
const cors = require('cors');
app.use(cors());
// Initialize the main project folder , this line allows talking between server and client side
app.use(express.static('website'));
// Setup Server
const port = 8000;
const server = app.listen(port , ()=>{console.log(`the server running on localhost: ${port}`);});
//GET function
app.get('/fakeData' , getFakeData); //string represents a url path >> / means home
function getFakeData (req,res) {
// body...
console.log(projectData);
res.send(projectData);
}
var project = [];
app.get('/all', sendData);
function sendData (request, response) {
response.send(project);
console.log(project);
};
//POST function
app.post('/addAnimal' ,addAnimal);
function addAnimal (req,res) {
// body...
newEntry = {
date: req.body.date,
temp: req.body.main.temp,
feeling: req.body.feeling
}
project.push(newEntry)
res.send(project)
console.log(project)
}
website/app.js
/* Global Variables */
//let baseURL = 'http://api.openweathermap.org/data/2.5/weather?q=Egypt&APPID=';
let baseURL = `http://api.openweathermap.org/data/2.5/weather?city=`;
let apiKey = '&APPID=bb95e29dbedc4d929be90b0dd99954e0';
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = d.getMonth()+'.'+ d.getDate()+'.'+ d.getFullYear();
//GET request to handle user input
document.getElementById('generate').addEventListener('click', performAction);
function performAction(e){
//Take user input
//const zipcode = document.getElementById('zip').value; //no
const feeling = document.getElementById('feelings').value;
const city = document.getElementById('zip').value;
//the fake api call
//getAnimal('/fakeAnimalData')
getTemp(baseURL ,city , apiKey )
.then (function(data) {
// body...
console.log(data)
postData('/addAnimal' ,{temp:data.main.temp ,date:newDate, feeling:feeling} )
//updateUI()
})
.then(
updateUI()
)
};
const getTemp = async(baseURL ,city , apiKey)=>{
const res = await fetch(baseURL+city+apiKey)
try{
const data = await res.json();
console.log(data)
return data;
}
catch(error){
console.log("error" , error);
}
}
//make a POST request to our route , POST to store locally user-input data
const postData = async(url='' , data={})=>{
//console.log(data);
const response = await fetch(url , {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
try {
const newData = await response.json();
console.log(newData);
return newData
}catch(error){
console.log("error", error);
}
}
const updateUI = async () => {
const request = await fetch('/all');
try{
const allData = await request.json()
console.log(allData);
document.getElementById('date').innerHTML = allData[0].date;
document.getElementById('temp').innerHTML = allData[0].temp;
document.getElementById('content').innerHTML = allData[0].feeling;
}catch(error){
console.log("error", error);
}
}
website/index.js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weather Journal</title>
<link href="https://fonts.googleapis.com/css?family=Oswald:400,600,700|Ranga:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id = "app">
<div class ="holder headline">
Weather Journal App
</div>
<div class ="holder zip">
<label for="zip">Enter Zipcode here</label>
<input type="text" id="zip" placeholder="enter zip code here">
</div>
<div class ="holder feel">
<label for="feelings">How are you feeling today?</label>
<textarea class= "myInput" id="feelings" placeholder="Enter your feelings here" rows="9" cols="50"></textarea>
<button id="generate" type = "submit"> Generate </button>
</div>
<div class ="holder entry">
<div class = "title">Most Recent Entry</div>
<div id = "entryHolder">
<div id = "date"></div>
<div id = "temp"></div>
<div id = "content"></div>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
There seems no issue in your url making. I have opened http://api.openweathermap.org/data/2.5/weather?city=cairo&APPID=bb95e29dbedc4d929be90b0dd99954e0 in browser and its returning HTTP 400 Bad Request as status code and due to 400 status code the browser is telling that the request failed.
Here is response. {"cod":"400","message":"Nothing to geocode"}
The original issue, it seems, is your city parameter that your are sending.
However if you change city parameter in your url to q, it seems to work.
http://api.openweathermap.org/data/2.5/weather?q=cairo&appid=bb95e29dbedc4d929be90b0dd99954e0
Here is response. {"coord":{"lon":31.25,"lat":30.06},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":295,"feels_like":293.65,"temp_min":294.82,"temp_max":295.15,"pressure":1015,"humidity":64},"visibility":10000,"wind":{"speed":4.1,"deg":290},"clouds":{"all":75},"dt":1584185538,"sys":{"type":1,"id":2514,"country":"EG","sunrise":1584158752,"sunset":1584201751},"timezone":7200,"id":360630,"name":"Cairo","cod":200}

Categories