Undefined body from post request in nodejs - javascript

I created the API in node js and in the POST method getting the body as undefined. How can I get the value that is passed using the fetch?
code for NodeJs-------------------------------------------
const express=require('express');
const app=express()
const port=3000
const fs=require('fs');
app.get('/',(req,res)=>{
res.send('hello world!');
});
app.get('/movies',(req,res)=>{
fs.readFile(__dirname+'/movies.json','utf-8',(err,data)=>{
res.send(data);
});
});
app.post('/movies',(req,res)=>{
console.log(req.body);
});
app.listen(port,()=>{
console.log(`app listening at http://localhost:${port}`)
});
code for HTML-------------------------
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form onsubmit="submitted(event)">
<input id="field" type="text" required="true">
<button type="submit">save</button>
</form>
</body>
<script>
function submitted(e){
e.preventDefault();
const value=document.getElementById('field').value;
await fetch('http://localhost:3000/movies',{
method:'POST',
body:{value},
mode:'no-cors',
headers:{
"Content-Type" : "application/json",
'Access-Control-Allow-Origin':'*'
}
});
}
</script>
</html>

Well you have got 2 problems:
1 Problem:
You need to stringify your body like
body:JSON.stringify({value})
2 Problem:
In express you need to parse your body. For that express provides .json()
const express=require('express');
const app=express()
const port=3000
const fs=require('fs');
app.use(express.json())

You need to use a middleware to parse the body correctly. It looks like you're sending JSON, so you'll need the bodyParser middleware provided by express.

Related

Not able to resolve the Promise on client side JS form express res.json

I am not able to debug or figure out why my request is logging raw HTTP response as shown in the image on the browser console once the expressjs server returns the JSON response. Let me kick in all relevant code and we can talk then
index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Infinite Scroll</title>
<script src="./infiniteScroll.js" defer></script>
</head>
<body>
<div id="testimonial-container"></div>
</body>
</html>
infiniteScroll.js
async function fetchAndAppendTestimonials(limit = 5, after = 0) {
const testimonials = await fetch('/testimonials');
console.log(testimonials);
}
fetchAndAppendTestimonials(5, 0);
I starting adding server.js incrementally so that I can bypass CORS to call the external API - 'https://api.frontendexpert.io/api/fe/testimonials';
server.js
const express = require('express');
const cors = require('cors');
const path = require('path');
const axios = require('axios');
const app = express();
const port = process.env.PORT || 80;
app.use(cors());
app.use(express.static('public'));
const API_BASE_URL = 'https://api.frontendexpert.io/api/fe/testimonials';
async function fetchTestimonials(limit = 5, after = 0) {
const testimonialUrl = new URL(API_BASE_URL);
testimonialUrl.searchParams.set('limit', limit);
// testimonialUrl.searchParams.set('after', after);
try {
const testimonials = await axios.get(testimonialUrl);
// console.log(testimonials);
return testimonials.data;
} catch (error) {
console.log(error);
return error;
}
}
app.get('/testimonials', async function (req, res) {
const testimonials = await fetchTestimonials(5, 10);
console.log(testimonials);
res.json(testimonials);
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(port, function () {
console.log('Server is running on port', port);
});
So on the client console, I am getting a log of raw HTTP response and not the actual JSON. On the express server function, I am getting the exact response. Don't know what is missing.
const testimonials = await fetch('/testimonials');
console.log(testimonials);
I am not able to debug or figure out why my request is logging raw HTTP response
Well, the first step would be to read the documentation for fetch:
Return value: A Promise that resolves to a Response object.
fetch returns a Response object wrapped in a promise.
You're unwrapping it with await and then logging the Response object.
It has various methods on it (such as the json method to wait for the body data to arrive and process it in various ways.
For example, if you want to get the JSON representation of the response body, you can do the following:
const response = await fetch('/testimonials');
const testimonials = await response.json()
console.log(testimonials);

Why can't I make a POST request to my Node.js Express server

I am trying to create a basic user registration system. All I just want right now is that once I register with the HTML form, I should be able to console.log it in the server. I tried doing this using fetch but I get this error:
Fetch API cannot load file:///C:/api/register. URL scheme "file" is not supported.
This is the code:
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Register</title>
</head>
<body>
<h1>Registration</h1>
<form id="reg-form">
<input type="text" placeholder="Username" id="username" autocomplete="off"/>
<input type="password" placeholder="Password" id="password"/>
<input type="submit" value="Submit Form"/>
</form>
</body>
<script>
const form = document.getElementById('reg-form')
form.addEventListener('submit', registerUser)
async function registerUser(event) {
event.preventDefault()
const username = document.getElementById('username').value
const password = document.getElementById('password').value
const result = fetch('/api/register', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({username, password})
}).then(res => res.json())
console.log(result)
}
</script>
</html>
Express Server:
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const app = express()
app.use(bodyParser.json())
app.post('/api/register', async (req, res) => {
console.log(req.body)
res.json({status: 'ok'})
})
app.listen(4000, () => console.log('Server up at 4000'))
I also tried doing the POST request directly from the HTML form element by setting the method attribute to POST and the action attribute pointing to the post route in my express server. When I try to submit the form, it redirects me to an empty page that says "Your file couldn't be accessed. It may have been moved, edited, or deleted."
What can I do to fix this?
You're opening the html file manually, not serving it from the server, so /api/register isn't going to your backend. Either serve the file from your server, or fetch localhost:4000/api/register
To serve your file from the server, you can do this:
const path = require('path');
...
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, '../relative/path/to/index.html'));
});
Instead of fetching /api/register try http://localhost:4000/api/register
also to print the result try this:
fetch('http://localhost:4000/api/register', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({username, password})
})
.then(res => res.json())
.then(data => console.log(data))

Node.js Express.js Send Jquery Ajax Post throws Constant Error - I'm stuck

I'm trying to make a very simple return coming from Node.js to Ajax. I'm using Express.js to make this possible.
I have code from the previous route that I did in order to write and manage JSON files and it works just fine.
The problem comes from the second route that always throws an error when I'm trying to make it return something with the JQuery ajax success method. It is the most simple form of send that I found but still doesn't work.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test 2</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</head>
<body>
Cod: <input type="text" name="cod" id="cod">
Text: <input type="text" name="text" id="text">
<button id="boton">PRUEBA</button>
<button id="getText">GET TEXT</button>
<script>
$('#boton').click(function() {
let cod=$('#cod').val();
let text=$('#text').val();
console.log(cod);
console.log(text);
$.ajax({
type: 'POST',
data: {
cod: cod,
text: text,
},
url: 'http://localhost:1337/prueba'
});
});
$('#getText').click(function() {
$.ajax({
type: 'POST',
data: {
},
success: (result) => {
console.log(result);
},
error: (result) => {
console.log('ERROR');
},
url: 'http://localhost:1337/getText'
});
});
</script>
</body>
</html>
app.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/prueba', function(req, res) {
// ... First Route. The code here works just fine so I don't add it here.
});
app.post('/getText', function(req, res) {
let text = "Hola mundo";
console.log(text);
res.send(text);
});
app.listen(1337, () => console.log('Started server at http://localhost:1337!'));
When you click the 'GET TEXT' Button it enters inside the '/getText' route in app.js and console.logs the text on the node.js terminal so that's not the issue.
The issue seems to come from the res.send() function.
In the browser console it logs 'ERROR' as it appears in the ajax error method associated to the 'GET TEXT' Button. I can't find a way to make it return success.
Could anyone help me? I'm so stuck with this project for work.
looks like a CORS issue... do you serve index.html from the same location?
It works serving index.html from node
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/prueba', function(req, res) {
// ... First Route. The code here works just fine so I don't add it here.
});
app.post('/getText', function(req, res) {
let text = "Hola mundo";
console.log(text);
res.send(text);
});
app.get('*', function (req, res) {
res.sendFile('index.html', {root: '.'})
})
app.listen(1337, () => console.log('Started server at http://localhost:1337!'));
There are several options for node/express, e.g. express middleware

Express how to re-direct json data through different endpoints

I'm pretty new to using express and the responses here on StackOverflow have been very confusing. What I have is JSON data that I am retrieving using app.get(). What I want is to modify this data and send it to my index.html file. I know that I can simply use the fetch function to get the data in my index file from the get endpoint but I need to use both the app.post() and app.put() function.
I'm having trouble understanding your question.
Here's a sample code that uses axios and plain vanilla javascript to get some data from backend and then in frontend, you can modify the data. You can replace axios for fetch and it'll still work.
app.js
const express = require("express");
const bodyParser = require("body-parser");
const port = 8000;
const app = express();
/* Simulating data, a better approach would be to use some storage like MySQL... */
let data = {
name: "Elon Musk",
age: "48",
height: "1.88m"
};
app.use(express.static("public"));
/* body-parser is required so the server can parse the data sent. */
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
/* get the data... */
app.get("/api/mydata", function(req, res) {
return res.json(data);
});
/* this is where the client will post the data */
app.post("/api/newdata", function(req, res) {
data.name = req.body.name;
data.age = req.body.age;
return res.json("OK!");
});
app.listen(port, function() {
console.log("Listening on 8000");
});
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="name" placeholder="Name..." value="">
<input type="text" id="age" placeholder="Age..." value="">
<button type="button" id="setValues">Change values!</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.js"></script>
<script>
window.addEventListener("load", function() {
axios.get("/api/mydata").then(function(res) {
document.getElementById("name").value = res.data.name;
document.getElementById("age").value = res.data.age;
})
});
document.getElementById("setValues").addEventListener("click", function() {
axios.post("/api/newdata", {
name: document.getElementById("name").value,
age: document.getElementById("age").value
}).then(function(res) {
console.log("Sent!");
})
})
</script>
</body>
</html>
If you have any questions, let me know!

node.js express is not receiving request

I am using express web framework and trying to make an $http request from angularjs. I am passing data to request from client but server is not receiving request for some unknown reasons. Please help.
server.js
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io')(server);
var path = require('path');
var fs = require('fs');
app.use(express.static(path.join(__dirname, 'public')));
app.post('/readTfile',function (req,res) {
console.log('i received a request');
console.log(req.body);
});
server.listen(3000);
And angular html
<html>
<head>
<title>File tream 2</title>
<script type="text/javascript" src="javascripts/angular.js"></script>
</head>
<body>
<h2>File tream 2 AngularJS</h2>
<div ng-app = "mainApp">
<div id="readfile" ng-controller = "Ctrl1">
<div>{{myfiledata}}</div> </br></br>
</div>
</div>
</body>
<script>
var mainApp = angular.module("mainApp",[])
mainApp.controller('Ctrl1', function ($scope, $http) {
var filename = 'D:\\myapp\\public\\test.txt';
var obj = {"filename" : filename};
$scope.myfiledata = 'result';
$http({
url: '/readTfile',
method: "POST",
data: JSON.stringify(obj),
//timeout: canceller.promise,
headers: {'Content-Type': 'application/json','charset' : 'utf-8'}
}).success(function(result) {
console.log(result);
$scope.myfiledata = 'result';
}).error(function(data, status) {
console.log(data);
});
});
</script>
</html>
On console i am getting undefined for req.body
i received a request
undefined
Please help to solve me this problem.
You will need middleware to read the body of the POST request from the incoming stream and to parse it from JSON to a Javascript object and put that into req.body. It does not just end up in req.body automatically. The usual middleware for a simple JSON body would be to use the body-parser middleware that is built into Express.
// other stuff here
// read and parse application/json
app.use(express.json());
app.post('/readTfile',function (req,res) {
console.log('i received a request');
console.log(req.body);
res.send("something");
});
And, for this middleware to work and automatically recognize that you sent JSON, you will have to make sure the post has set the right content type.
Note, there is different middleware for different content types. The code above is for application/json. If you are doing a vanilla form post, that would typically have a content-type of application/x-www-form-urlencoded and you would use:
app.use(express.urlencoded());
The middleware shown here will automatically detect which content-type is available only operate on a content-type that matches their functionality so you can even have both of these middleware present.

Categories