issue with react ui communicating with node - node.js

This is the react fetch:
var json = {
json: JSON.stringify({
a: 1,
b: 2
}),
delay: 3
};
fetch('/saveInfo', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify(json.json)
})
.then(function (response) {
return response.json();
})
.then(function (result) {
alert(result);
console.log("The file was saved!");
})
.catch (function (error) {
console.log('Request failed');
});
This is node:
<pre>
var express = require('express');
module.exports = function(app) {
var router = express.Router();
router.get('/', function (req, res) {
console.log('from node');
console.log(req);
res.json({status: 'UP'});
});
app.use("/saveInfo", router);
}
</pre>
The code above doesn't work with the 2nd parameter to the fetch.
But when I execute it w/o the second parameter to fetch as below:
fetch('/saveInfo')
.then(function (response) {
return response.json();
})
.then(function (result) {
alert(result);
console.log("The file was saved!");
})
.catch (function (error) {
console.log('Request failed');
});
Works fine and is able to communicate to the node program.
Can any one help me with this what is wrong. I wanted to send the react's UI forms state t the node program.

You need to add a handler for the POST requests also.
In the fetch method for 1st case, you have given the method type as POST but node doesn't have any handling for that.
However, when you don't give the second parameter, it is considered as GET request and is intercepted by router.get.
Just add this in the node (before app.use line):
router.post("/", function (req, res) {
console.log('from node');
console.log(req);
res.json({status: 'UP'});
});
It will enable node to listen for POST requests.
Edit: To have access to post request body params in router.post, you need body-parser package. Install this package and add these two lines before initializing the express router:
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
Read http://jilles.me/express-routing-the-beginners-guide/ for detailed explanation

Related

Why data not getting posted to the route?

I have an application wherein after getting the data from user, I am posting it to the /create
route.
However upon making a post request, it gives me error:
POST http://localhost:5000/create 404 (Not Found)
The code for making post request:
submitbtn.addEventListener('click', (e) => {
e.preventDefault();
const data=validateForm();
if (data) {
postData(data);
console.log("submitted");
}
})
async function postData(data) {
await fetch('http://localhost:5000/create', {
method: 'POST',
body: {
title: `${data.title}`, content: `${data.text}`
},
headers: {
'Content-Type': 'application/json'
}
})
}
Handling the post request on my server:
const express=require('express');
const app= express();
const router=express.Router();
const News=require('./news/news');
app.use(express.static('./public'));
router.post('/create',(req,res)=>{
res.send("Successful");
})
app.listen(5000,()=>{
console.log("Server listening on 5000 port");
})

Issues with nodejs' request and pipe

I'm having an issue with the following code. I'm trying to make a POST request (json) to a URL using pipe but I get the error "write after end" - Internal Server Error. Can someone please help?
test: function( req, res, next) {
var requesty = request.post({
url: dataUrl,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
req.pipe(requesty).on('error', function (error) {
logger.withRequestLog(res, 'error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
next(error);
}).pipe(res);
}
You are getting error because of body: JSON.stringify(body). You can't (also don't need) to pass body as when you are piping raw bytes are being piped as well. Also This middleware should be FIRST as you don't want to use bodyParser etc which will read the stream and make it empty.
Below is an working example where I am proxying my request to one my routes(It can be external also):
const express = require('express');
const app = express();
const request = require('request');
const bodyParser = require('body-parser').json();
const dataUrl = '/employees'
app.use(dataUrl, bodyParser, (req, res)=>{
res.json({
body: req.body || {},
method: req.method,
param: req.params,
headers: req.headers,
url: req.url
});
})
app.use('/', (req, res) => {
var requesty = request({
url: 'http://localhost:8080'+dataUrl,
headers: {
'Content-Type': 'application/json'
},
})
req.pipe(requesty).on('error', function (error) {
console.log('error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
}).pipe(res);
});
app.listen(8080, () => {
console.log('started');
})
Note: You don't need to specify method as it will automatically be passed. From the doc:
You can also pipe() from http.ServerRequest instances, as well as to
http.ServerResponse instances. The HTTP method, headers, and
entity-body data will be sent.

POST an item to JSON server db- Angular

I'm trying to POST an Item to my db in my json server. I'm sending the POST request from Angular. When I do so, I get the following error:
Note: when I do the get in a the GET end point it works fine. I'm very new on the server side
POST ERROR 404:
Http failure response for http://localhost:3000/addMember: 404 Not Found
SERVER.JS
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
....
app.use(cors());
app.use(express.static('assets'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.disable('x-powered-by');
app.use(xssFilter());
app.use(nosniff());
app.set('etag', false);
app.use(
helmet({
noCache: true
})
);
app.use(
hsts({
maxAge: 15552000 // 180 days in seconds
})
);
app.use(
express.static(path.join(__dirname, 'dist/softrams-racing'), {
etag: false
})
);
app.get('/api/members', (req, res) => {
request('http://localhost:3000/members', (err, response, body) => {
if (response.statusCode <= 500) {
res.send(body);
}
});
});
// TODO: Dropdown!
app.get('/api/teams', (req, res) => {
request('http://localhost:3000/teams', (err, response, body) => {
if (response.statusCode <= 500) {
res.send(body);
}
});
});
// Submit Form!
app.post('/api/members', function(request, response) {
request.post('http://localhost:3000/members', (err, response, body) => {
if (response.statusCode <= 500) {
req.send(body);
}
});
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/softrams-racing/index.html'));
});
app.listen('8000', () => {
console.log('Vrrrum Vrrrum! Server starting!');
});
ANGULAR
addMember(memberForm: Member) {
this.http.post(`${this.api}/addMember`, memberForm).subscribe(
data => {
console.log('POST Request is successful ', data);
},
error => {
console.log('Error', error);
}
);
}
UPDATE:
in my console i see this POST /addMember 404 12.105 ms - 2 and If i go to http://localhost:3000/addMember directly in the browser I see an empty object {} and if I go here http://localhost:3000/ I see this message To access and modify resources, you can use any HTTP method GET POST PUT PATCH DELETE OPTIONS
The issue here is that you are making your POST request to a route which your JSON server does not handle. Change the URL to http://localhost:3000/members, and it should work fine!
(The routes on a json-server correspond to the elements in your db.json file.)
Try to change your code like this:
addMember(memberForm: Member) {
this.http.post(`${this.api}/api/addMember`, memberForm).subscribe(
data => {
console.log('POST Request is successful ', data);
},
error => {
console.log('Error', error);
}
);
}
From the error it is shown that your service is expecting the request at http://localhost:3000/api/addMember but your console.log shows that you are sending post request at http://locatlhost:3000/addMember

NextJS and React: Cannot read property 'email' of undefined

I try to send data from my client to my server. For that, i use React with NextJS, because you have the server and client-side in one app.
I use the following handleSubmitFunction:
handleSubmit() {
const email = this.state.email;
fetch('/', {
method: 'POST',
body: email,
});
}
and this is my server.js file in the located in / at my project
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
//parse application
server.use(bodyParser.urlencoded({ extended: false}))
//parse application/json
server.use(bodyParser.json())
server.post('/', (req, res) => {
console.log(req.body.email);
res.end("success!");
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
When the handleSubmit Function is running, i get the following Output from the Server Console:
Cannot read property 'email' of undefined
Where exactly is my mistake?
I have little experience in node JS environments. I would be very grateful if you could show me concrete solutions. Thank you for your replies.
It seems you have to parse header and JSON.stringify the email.
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
}).then((res)=> console.log('Worked'))

TDD Test first Nodejs express Rest Api - unit testing middlewere / controllers / routes

I'm trying to figure out how to test first my node js rest api app.
so far i've been using nock to intercept and mock any http call and by that test my service as a component. (component testing?)
i want to start unit testing my app so my test pyramid is more balanced and tests will be easier to write.
searching the web i got to this approach:
http://www.slideshare.net/morrissinger/unit-testing-express-middleware
var middleware = require('./middleware');
app.get('example/uri', function (req, res, next) {
middleware.first(req, res)
.then(function () { next(); })
.catch(res.json)
.done();
}, function (req, res, next) {
middleware.second(req, res)
.then(function () { next(); })
.catch(res.json)
.done();
});
(basicly pulling the middleware out and testing it)
since this presentation is from 2014 i was wondering what are the current up to date methods for unit testing express apps?
I had the same problem and I used another approach.
First I created a file included in all my tests that start node and export a function to send an http request:
process.env.NODE_ENV = 'test';
var app = require('../server.js');
before(function() {
server = app.listen(3002);
});
after(function(done) {
server.close(done);
});
module.exports = {
app: app,
doHttpRequest: function(path, callback) {
var options = {
hostname: 'localhost',
port: 3002,
path: path,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Content-Length': 0
}
};
var req = http.request(options,
function(response) {
response.setEncoding('utf8');
var data = '';
response.on('data', function(chunk) {
data += chunk;
});
response.on('end', function() {
callback(data, response.statusCode);
});
});
req.end();
}
}
Then I called my server using the previous declared method:
var doHttpRequest = require('./global-setup.js').doHttpRequest;
var expect = require('chai').expect;
describe('status page test', function() {
it('should render json', function(done){
doHttpRequest('/status', function(response) {
expect(JSON.parse(response).status).to.eql('OK');
done();
})
});
});

Resources