nodejs post method not getting called - node.js

I found my question was asked a year ago here app.post() not working with Express but the code written there is outdated (the way bodyparser was added doesn't work anymore as well as function mentioned below) plus the asker never chose an answer so the question was never solved.
Here's my code
const express = require("express");
const db = require("mysql");
const app = express();
const bodyParser = require("body-parser");
const multer = require("multer"); // v1.0.5
const upload = multer(); // for parsing multipart/form-data
const http = require("http");
const path = require("path");
app.set("view engine", "jade");
app.set("views", path.join(__dirname));
console.log("before");
app.listen(8000, () => {
console.log("Server started!");
console.log("within");
});
console.log("after");
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.post("/", function(req, res) {
console.log("hit here in post");
res.render("index.jade", {});
console.log("hit here in post");
res.json({ name: "John" });
res.status(500).json({ error: "message" });
res.end();
});
app.get("/", function(req, res) {
res.render("index.jade", {});
console.log("hit here in get");
console.log(req.body);
});
Here's the output.
before
after
Server started!
within
hit here in get
{}
I even tried to wrap the app sets and uses in app.configure like the asker of the other question to see if that was the issue but that configure function doesn't seem to exist anymore because I got an error about it.
Also I should probably note. My routing here is correct. I haven't made a views subfolder yet so that's why I have it written as it is.
Update
I think I may have spotted the issue but I don't understand why it's occurring. In the network tab of the browser I see that GET is getting 404 error because of a favicon.ico request but I don't understand where that request is coming from. I've seen the serve-favicon npm module to support it but didn't want to added because I never intended to add a favicon image to my server. I don't even understand how that would work.
Reply to last comment by James
What do you mean by I configure the middleware after it has started? Are you referring to the fact that the post method is written after port listening has started? Also if that's the reason why post isn't executing how come the get method executes regardless of that? I'm not holding back any server code aside from code I currently have commented out for the moment but that code I posted is my main index.js file and it's the only file I modified from the standard npm init project. I haven't setup any routes because I don't see the need to do so (even when I add react since my project is simple in concept of communication between reactjs, nodejs and a database "hence my frustration") which is why I'm trying to have get and post only access the root directory.

favicon is automatically requested by the browser. it is the icon used in the browser tab or url address bar
Add this, before app.get():
app.all('/', function(req, res, next) {
console.log({method: req.method, url: req.url});
next();
});

Related

Unable to receive files in request using express-fileupload

I use a REST client to test my app (Insomnia and postman). My app literally does nothing:
const express = require('express');
const app = express();
const fileUpload = require('express-fileupload');
app.use(express.json())
app.use(fileUpload());
app.post('/', fileUpload(), function(req, res) {
console.log(req.files)
res.send('a')
});
const PORT = 9999;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}...`);
});
Whenever I try to upload a file to this service req.files is undefined. I took this code from express docs page and from a few stackoverflow questions and it just doesn't work for me. Content-length is good (40k seems right)
Content-type is auto set by my REST client. Do I have to change this?
I tried simply printing whole request object and body is empty and files is not even present there
So for anyone wondering. fileupload requires form-data Content-type. Moreover, it also requires a file to have a "key" within this form-data. It's a shame documentation fails to mention this.
Just do one thing: remove file fileUpload() from post endpoint and check, find below code for your reference.
app.post('/', function(req, res) {
console.log(req.files)
res.send('a')
});

AWS Lambda: Express res.render always sends "internal server error"

My goal is to port my existing Node-Express-Pug-Mongo website onto Amazon Web Services, but I'm running into an error with rendering Pug files on Lambda. Whenever I attempt to run res.render, the page shows this: {"message": "Internal server error"} after a timeout of 3000 milliseconds (from viewing the CloudWatch console).
I've tried throwing console.log everywhere to get more information on what is causing the error, but to no avail.
res.send works with text
res.sendFile works with the Pug file that I am trying to use in the function
res.render accepts a callback input, which I have attempted to use to catch errors, but no logs exist on the console.
I've tried different ways of inputting the pug file, as you can see for the five different get URLs. All of them do the same thing.
I've tried changing to Jade, but I get the same issues.
NOTE: On a local server, the syntax in render1 and render3 are the ones that work.
ALSO: On the local server, using callbacks does cause the function to hang. I have attempted this with and without callbacks, and the issue is the same.
'use strict'
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const router = express.Router();
app.set('view engine', 'pug');
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));
app.set('views', path.join(__dirname, 'views'));
router.get('/sendfile', function(req, res){
res.sendFile(__dirname+"/views/test.pug");
});
router.get('/sendtext', function(req, res){
res.send('hello!');
});
router.get('/render1', function(req, res){
res.render('test', {}, function(err){
console.log(err);
});
});
router.get('/render2', function(req, res){
res.render('.test', {}, function(err){
console.log(err);
});
});
router.get('/render3', function(req, res){
res.render('./test', {}, function(err){
console.log(err);
});
});
router.get('/render4', function(req, res){
res.render('./views/test', {}, function(err){
console.log(err);
});
});
router.get('/render5', function(req, res){
res.render(__dirname+'/views/test', {}, function(err){
console.log(err);
});
});
app.use('/', router);
// Export your express server so you can import it in the lambda function.
module.exports = app;
None of these render functions work. It always times out after 3 seconds and returns {"message": "Internal server error"}. I've tried everything I could think of. Is this an Express issue? Do I have to do something different to configure Pug? It works exactly as expected when I use the exact same module on a local Node.js server.
After a lot of digging, I figured out the issue.
My Lambda function ("server") wasn't allocated enough RAM. When I attempted to load Pug, it would overload and crash.
The default is 128MB, so turning it up to 384MB-ish worked fine.

Express CORS not working

I just started my nodejs express template buy cors is not working.
I used npm install cors --save
here is the file:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
var corsOptions = {
origin: 'https://example.com/',
optionsSuccessStatus: 200
};
app.get('/', cors(corsOptions), function(req, res, next) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.get('/tt', function(req, res, next) {
res.json({ message: 'hooray! welcome to our api!' });
});
var port = process.env.PORT || 3030;
app.listen(port);
console.log('Magic happens on port ' + port);
Now with the above code when I access localhost:3030/tt or / I still see the content and I shouldn't
What's wrong with this.. I just lost like 2 hours working on this.. :(
At this time I would like not to use CORS, but in near future when my app is finished, I want to allow incoming calls only from my project, since this app will be my API.
The behavior you are describing seems is what I would expect.
CORS won't help you filter out incoming calls on the server. In this case the browser's CORS check won't kick-in as it appears you are directly typing in the URL in the browser. Browser does a CORS check only when the the webpage loaded from a particular domain tries to access/submit to a URL in a different domain.
A different way to think about CORS. CORS is intended to protect the user sitting in front of the browser, and not the server-code that is being accessed.

req.body empty out of nowhere when sending POST with express and node

I have a node app on heroku that is using express to act as a REST API.
On thursday and friday of last week, it was working just fine, when i would post using REST Easy through firefox. I hope on Saturday morning and the request would no longer send the data.
I can see the data in the payload of the request, but it never makes it to the request body.
import express from 'express';
import bodyParser from 'body-parser';
let app = express();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.set('port', (process.env.PORT || 5000));
let router = express.Router();
router.post('/', (req, res) => {
res.json(req.body);
});
app.use('/api', router);
app.listen(app.get('port'), () => {
console.log('Node app is running on port', app.get('port'));
});
All i get back is an empty object, which i believe is the by product of the bodyParser.json()
I am sending it as form data using application/x-www-form-urlencoded, and i have even tried checking to make sure it wasn't parsed twice, which would cause the key to be the body data using
try {
req.body = JSON.parse(Object.keys(req.body)[0])
} catch (err) {
req.body = req.body
}
I am completely stumped at this point, any thoughts?
Looks like it was something with that addon, just stopped working overnight. Had to download chrome and use Advance Rest Client, and that showed the data coming through. Thanks for jumping on the question #p0k8_

Avoid global variables in Node, how to return the body of a request from a POST call

I'm still new to Node so I'm sure I'm doing something wrong, but some searching isn't helping so here we are.
I'm making a request to an API to get weather data. I can get the data and log it to the console no problem, but I'm having trouble getting the body of the request to end up in the response to the original POST.
var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// make the web server use body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
console.log("server starting on " + appEnv.url);
});
// Send information from the weather API to the console
app.post('/processWeather', function (req, res) {
requestString = 'http://api.openweathermap.org/data/2.5/weather?id=7839805&appid=xxxxxxxx';
request(requestString, function(err, res, body){
if (!err && res.statusCode == 200) {
console.log(body);
}
});
//redirect back to homepage after getting the weather
res.redirect("/");
});
So the problem with this is that I can't simply use the body variable in the app.post callback. I'm suspicious this is to do asynchronous logic but I'm as I'm new I can't wrap my head around the best way to do this without using a global variable to temporarily store the body variable. How can I get the contents of the body variable sent back to the browser? Any help greatly appreciated. Cheers.
Don't use global variables unless it's absolutely necessary!
You can use session.
req.session['weather'] = weatherData; // Weather data
res.redirect("/");
You can use a lot of other ways also. But this is what I'd prefer.
I figured out what I needed. All I had to do was place the request in the res.send
res.send(request(requestString));

Resources