Heroku - specific route works locally but not on production - javascript

I have a node project which was deployed to an Heroku app.
The deploy was successful and i can open the app , but there is one route to which i'm getting a "Cannot GET" error (404) while other routes on the same page are working as expected.
Locally everything is working as expected and when i run heroku local in cmd i can see the response coming back from that function but i can't say the same for trying it from heroku app link.
server.js
'use strict';
var http = require ('http');
var url = require('url') ;
var express= require('express');
var app= express();
var port = process.env.PORT || 3000;
var mongoose = require ('mongoose');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
mongoose.connect (db_details);
var conn=mongoose.connection;
var trip = require ('./Schemas/trip');
var user = require ('./Schemas/user');
app.all('/*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type,accept,access_token,X-Requested-With');
next();
});
conn.on('error', function(err) {
console.log('connection error: ' + err);
process.exit(1);
});
conn.once('open',function() {
console.log('connected successfuly to the remote DB');
app.use(require('./Routes')); //API routings
app.listen(port);
console.log("listening on port "+port+" and waiting for WS requests");
});
Routes/api/trip.js
'use strict'
var router = require('express').Router();
var mongoose = require('mongoose');
var trip = require ('../../Schemas/trip');
var user = require ('../../Schemas/user');
var Gmap = require ('../../TripBuilder/builder');
// get all trips
router.get('/getTrips', function(req, res) {
trip.find({},'trip_id Trip_Name Country City', function(err, trips) {
res.send(trips.reduce(function(userMap, item) {
userMap[item.id] = item;
return userMap;
}, {}));
});
});
// create new trip
router.post('/addNewTrip', function(req, res,next) {
let newTrip = new trip ({"Trip_Id":req.body.Trip_id,"Trip_Name":req.body.Trip_Name,"Trip_Date":req.body.Trip_Date,
"Trip_Owner":req.body.Trip_Owner,
"Country":req.body.Country,"City":req.body.City,"status":"Pending","Days":[],"Sites":[]});
return newTrip.save().then(function(){
return res.send("A Trip was created");
}).catch(next);
});
router.post('/addUserToTrip', async function(req, res,next) {
user.find({'email':req.body.email},'first_name last_name email', function(err,obj) {console.log("print " +obj); });
let secUser = {"Trip_Id":req.body.Trip_id};
});
router.post('/createRoute', function(req, res,next) {
var map=new Gmap();
var origins = ['Big Ben, London, UK','Bridge St, Westminster, London SW1A 2JR, UK','Palace of Westminster, Westminster, London SW1A 0PW, UK','Whitehall, Westminster, London SW1A 2ET, UK'];
var destinations =['Big Ben, London, UK','Bridge St, Westminster, London SW1A 2JR, UK','Palace of Westminster, Westminster, London SW1A 0PW, UK','Whitehall, Westminster, London SW1A 2ET, UK'];
map.calcRoute(origins,destinations).then(function(result){
map.longestroute=result; //save start and end
origins.splice(origins.indexOf( map.longestroute.origin), 1);
origins.splice(origins.indexOf( map.longestroute.destination), 1);
map.waypoints=origins;
map.setRoute(map.longestroute.origin,map.longestroute.destination,map.waypoints).then(function(route){
return res.send(route);
});
}).catch(next);
});
module.exports = router;
Calling https://APP-NAME.herokuapp.com/api/trip/createRoute returns "Cannot GET /api/trip/createRoute", while calling https://APP-NAME.herokuapp.com/api/trip/getTrips returns a response.
Heroku logs seems to record the request without any special exceptions but nothing is coming back.
I added "res.send("ok");" inside "createRoute" just to see at least that will be sent back but nothing.
Package.json
"name": "tripin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"engines": {
"node": "9.8.0"
},
"author": "",
"license": "ISC",
"dependencies": {
"#google/maps": "^0.4.6",
"body-parser": "^1.18.2",
"express": "^4.16.2",
"http": "0.0.0",
"https": "^1.0.0",
"inspect-process": "^0.5.0",
"mongoose": "^5.0.9",
"node-dev": "^3.1.3",
"package.json": "^2.0.1",
"request": "^2.85.0"
}
}
Thanks
Edit:
router.post('/createRoute) and router.get('/createRoute) were attempted.
didn't work in either case

Your error messages is complaining about the GET, so it wants to GET "createRoute".
The create route path is a POST (so your HTTP request should be a POST).
You can check this by implementing a GET, and give a response your will reconize..
router.get('/createRoute', function(req, res) {
// .. your reconizalbe response here ..
res.send("Oops I did a GET, but wanted to POST");
}
and/or test with tool which can invoke the POST, like Postman or some other tool.

Ok , so as we all know programming rules state that the smaller the issue is, the harder it is to find it.
I managed to find out the solution:
I had my project duplicated in heroku - once in the root folder and once in its folder like it should be.
That threw off any routing i tried.
cleaning up heroku and re-deploy did the trick.
Thank you all for trying to help

Related

Cannot GET api route (node.js, express)

JS noob, I'm trying to follow a course on node.js API creation. I'm doing everything by the book instruction by instruction. This is the server.js file, as specified in the course:
const http = require('http');
const app = require('./app');
const normalizePort = val => {
const port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
};
const port = normalizePort(process.env.PORT || 3000);
app.set('port', port);
const errorHandler = error => {
if (error.syscall !== 'listen') {
throw error;
}
const address = server.address();
const bind = typeof address === 'string' ? 'pipe ' + address : 'port: ' + port;
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges.');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use.');
process.exit(1);
break;
default:
throw error;
}
};
const server = http.createServer(app);
server.on('error', errorHandler);
server.on('listening', () => {
const address = server.address();
const bind = typeof address === 'string' ? 'pipe ' + address : 'port ' + port;
console.log('Listening on ' + bind);
});
server.listen(port);
I run this server from the console and cUrl and postman requests give me a 404 (Cannot GET) when I send get requests to http://localhost:3000/api/stuff, the route I specified in app.js:
const express = require('express');
const app = express();
app.use('http://localhost:3000/api/stuff', (req, res, next) => {
const stuff = [
{
message: "this is a JSON"
},
{
message: "this is also a JSON"
}
];
res.status(200).json(stuff);
});
My package.json seems alright:
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"node": "^15.2.1"
}
}
In app.js I tried app.get instead of app.use, and generating the JSON directly into the res.status(200).json().
I really suspect the issue is in the server.js, I tried messing around with it to no avail (feeding normalizePort() a string instead of an integer, eliminating process.env.port, simplifying the switch where it checks if port 3000 is free).
I have of course checked for similar issues in SO, but nothing seemed to match my specific problem.
node --version
v13.11.0 (the course is based on an old version too)
A URL consists of multiple parts:
scheme
authority (including host and port)
path
query
fragment
Parsing http://localhost:3000/api/stuff results in:
scheme: http
authority
host: localhost
port: 3000
path: /api/stuff
app.use does not expect a complete URL. It just expects the path part: app.use('/api/stuff',
You can pass more than just a simple string. Examples can be found in the documentation.

How to save data using mongodb query in middleware in nodejs

I want to save data using mongodb query using middleware in node.js. please provide some code with example?
Try this. It works both for insert and update (upsert).
// app.js
const express = require('express');
const bodyParser = require('body-parser');
const MongoClient = require('mongodb').MongoClient;
const mongodb_url = process.env.MONGO_URL || "mongodb://localhost:27017";
const mongodb_dbname = 'test_db';
const port = process.env.PORT || 3006;
const app = express();
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json({ extended: true}));
app.post('/api/post/:identifier', (req, res) => {
const identifier = req.params.identifier;
const content = req.body.payload;
MongoClient.connect(`${mongodb_url}`, { useNewUrlParser: true }, (err, client) => {
if (!err) {
let db = client.db(mongodb_dbname);
db.collection('posts')
.updateOne(
{ identifier: identifier },
{ $set: { content: content } },
{ upsert: true }
)
.then((output) => {
res.status(202).send({ message: "Sent"});
})
.catch((error) => {
res.status(500).send({
error_code: 500,
error_message: `Error while updating data - ${error}`
});
});
client.close();
} else {
res.status(500).send({
error_code: 500,
error_message: 'Error while connecting to database'
});
}
});
});
app.listen(port, () => {
console.log(`API bootstrapped on port ${port}...`);
});
Use the following package.json file:
{
"name": "mongo-upsert",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"mongodb": "^3.6.0"
}
}
When invoked as localhost:3006/api/post/my-post with a request body containing:
{
"payload": "Hello world"
}
This code is going to upsert a MongoDB document like:
{
"_id" : ObjectId("5f3d272cbd52c9c109ea9baa"),
"identifier" : "my-post",
"content" : "Hello world"
}
Prerequisites for the above code to work:
To have a working installation of mongodb
To have a database named test_db
To have a collection named posts
In this example, we are adding a post content, identified by an identifier, which for the sake of simplicity I have added as a path param in the POST definition.
Install dependencies using npm install.
Run the app using npm start.
Good luck.
Look into W3Schools NodeJS MongoDB.
I don't have enough rep to comment so here's an answer.

FetchError: request to http://localhost:3000/api/projects failed, reason: connect ECONNREFUSED 127.0.0.1:3000 (Express/Next.Js) [duplicate]

This question already has an answer here:
Fetch error when building Next.js static website in production
(1 answer)
Closed 9 months ago.
I have an API route which upon request gets me the data I want when the Project page (component) is loaded as shown below.
http://localhost:3000/api/projects
When I load the page where I request for that data inside getInitialProps() within pages/projects.js it shows data coming through which is what I want as shown below, so far so good.
console logs data coming through from custom express API route I have made
The code for that is here:
pages/projects.js
import React, { Component } from "react";
import Layout from "../components/Layout";
import Siema from "siema";
import Head from "next/head";
import fetch from "isomorphic-unfetch";
export default class extends React.Component {
componentDidMount() {
this.siema = new Siema({
loop: false
});
}
prev = () => {
this.siema.prev();
};
next = () => {
this.siema.next();
};
render() {
return (
<Layout>
<Head>
<title>Jesal Patel | Projects</title>
</Head>
<div className="container">
<section>
<div className="projects">
<div className="siema">
<div>
<img src="(ignore this the img is showing on stackoverflow post.)" />
<div className="overlay">
<div id="overlay_title">Dextero</div>
<div id="overlay_description">
I developed a multi-touch mobile game for stroke patients
to rehabilitate their finger coordination and dexterity.
</div>
<div id="overlay_tech">Java, Android, LibGDX, SQLite</div>
</div>
</div>
</div>
<div />
<button onClick={this.prev}>Prev</button>
<button onClick={this.next}>Next</button>
</div>
</section>
</div>
</Layout>
);
}
static async getInitialProps({ req }) {
//This fetch is the reason why my project won't build
const result = await fetch("http://localhost:3000/api/projects");
const projects = await result.json();
console.log(projects);
return { projects };
}
}
The Problem:
Now the problem begins when I run next-build and the following error throws during it: EDIT: I didn't paste the error properly. NOTE: I run now-buildscript which exports the project and that's my problem, it's what's causing me problems
I:\Next.js\website>npm run now-build
> website#1.0.0 now-build I:\Next.js\website
> next build && next export -o dist
Creating an optimized production build ...
Compiled successfully.
┌ /
├ /_app
├ /_document
├ /_error
├ /contact
└ /projects
> using build directory: I:\Next.js\website\.next
copying "static" directory
copying "static build" directory
> No "exportPathMap" found in "next.config.js". Generating map from "./pages"
launching 11 threads with concurrency of 10 per thread
[====-] 4/5 80% 160/s 0.0s { FetchError: request to http://localhost:3000/api/projects failed, reason: connect ECONNREFUSED 127.0.0.1:3000
at ClientRequest.<anonymous> (I:\Next.js\website\node_modules\node-fetch\lib\index.js:1444:11)
at ClientRequest.emit (events.js:189:13)
at Socket.socketErrorListener (_http_client.js:392:9)
at Socket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
message:
'request to http://localhost:3000/api/projects failed, reason: connect ECONNREFUSED 127.0.0.1:3000',
type: 'system',
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED' }
{ message:
'request to http://localhost:3000/api/projects failed, reason: connect ECONNREFUSED 127.0.0.1:3000',
type: 'system',
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED' }
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! website#1.0.0 now-build: `next build && next export -o dist`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the website#1.0.0 now-build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Jesal\AppData\Roaming\npm-cache\_logs\2019-03-19T04_10_45_930Z-debug.log
I understand that it's due to this line const result = await fetch("http://localhost:3000/api/projects");, but I don't know what to do to enable it to build. I am new to MEAN stack. I'm not sure if I have to create that route externally somewhere global for it to work fine? I don't know if that will fix it or if it's something else.
I have used Express and Mongoose with this application and the code for these can be found below along with the package.json and next.config.js files.
server/index.js
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();
const routes = require("./routes/index.js");
var mongoose = require("mongoose");
const PORT = process.env.PORT || 3000;
const dbName = "MySite";
const MONGO_URL =
"mongodb+srv://admin:<hidden for privacy>#cluster0-5cjs1.mongodb.net/MySite?retryWrites=true";
app
.prepare()
.then(() => {
mongoose.connect(MONGO_URL, { useNewUrlParser: true });
mongoose.Promise = global.Promise;
mongoose.connection.on("open", function() {
console.log("mongodb is connected!!");
});
const db = mongoose.connection;
model = db.modelNames();
db.on("error", console.error.bind(console, "MongoDB connection error:"));
const server = express();
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use("/api", routes);
server.use((req, res, next) => {
// Also expose the MongoDB database handle so Next.js can access it.
req.db = db;
next();
});
server.get("*", (req, res) => {
return handle(req, res);
});
server.listen(PORT, () => {
console.log("Server is up and running on port number " + PORT);
});
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
server/routes/index.js
const express = require("express");
const router = express.Router();
const project_controller = require("../controllers/project_controller");
router.get("/projects", project_controller.projects_list);
module.exports = router;
server/models/project_schema.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ProjectSchema = new Schema(
{
name: String,
description: String,
tech: String
},
{ collection: "project" }
);
module.exports = mongoose.model("Project", ProjectSchema);
server/controllers/project_controller.js
const Project = require("../models/project_schema");
exports.test = function(req, res) {
res.send("Greetings from the Test controller!");
};
exports.projects_list = function(req, res) {
var documents = Project.find({}, function(err, docs) {
if (err) throw err;
res.send(docs);
return docs;
});
};
exports.project_create = function(req, res) {
let project = new Project({
name: req.body.name,
description: req.body.description,
tech: req.body.tech
});
project.save(function(err, project) {
if (err) {
console.log("Unsuccessful");
}
console.log("Saved!");
});
};
package.json
{
"name": "website",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon server/index.js",
"now-build": "next build && next export -o dist",
"build": "next build",
"start": "next start -p 8000"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"#engineerapart/nextscript": "^1.0.2",
"#zeit/next-css": "^1.0.1",
"#zeit/next-typescript": "^1.1.1",
"body-parser": "^1.18.3",
"bootstrap": "^4.3.1",
"co": "^4.6.0",
"cross-env": "^5.2.0",
"express": "^4.16.4",
"file-loader": "^3.0.1",
"isomorphic-unfetch": "^3.0.0",
"jquery": "^3.3.1",
"mongodb": "^3.1.13",
"mongoose": "^5.4.19",
"next": "^8.0.4-canary.10",
"next-compose-plugins": "^2.1.1",
"next-images": "^1.0.4",
"nodemon": "^1.18.10",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-slick": "^0.23.2",
"siema": "^1.5.1",
"superagent": "^4.1.0",
"url-loader": "^1.1.2"
}
}
next.config.js
const withCSS = require("#zeit/next-css");
const withImages = require("next-images");
const withPlugins = require("next-compose-plugins");
module.exports = {
crossOrigin: "anonymous"
};
module.exports = withPlugins([withImages, withCSS]);
module.exports = withImages();
// module.exports = withCSS();
module.exports = {
target: "serverless"
};
module.exports = withCSS({
webpack: function(config) {
config.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: "url-loader",
options: {
limit: 100000,
name: "[name].[ext]"
}
}
});
return config;
}
});
UPDATE: This is an update to Prabhakar Pandey's response, to let you guys know, I always killed the server when running the now-buildcommand, Also, to be very clear as I mentioned before on my first edit of this post, that it's the 2nd part of that command which is failing with error, which is next export -o distnot next build, that works fine! Also, I'm on Windows OS not Mac OS.
This happens because you want to run an application on a port which is already being used.
you can check the application running on a port with these commands:
For macOS El Capitan and newer (or if your netstat doesn't support -p), use lsof
sudo lsof -i tcp:3000
For Centos 7 use
netstat -vanp --tcp | grep 3000
Also if wnat to kill any process you can use
kill -9 `PID`
when port is empty you try your application by rebuilding it should work

Record all remote calls in a nodejs express app for testing

The goal is to have recored api tests. This test are kind of integration tests, they load the whole app with all its middlewares and intercepts the external http calls and records them.
In Python world exists "WebTest" and "VCRPY" for that.
The app:
'use strict';
const express = require('express');
const request = require('superagent');
var app = express();
app.get('/hammer/version', function(req, res) {
request
.get('http://httpbin.org/get')
.end(function(err, response) {
console.log(response.body);
res.status(200).json({
version: '0.1.0',
url: response.body.url
});
});
});
module.exports = app;
The test:
/* global describe, it */
'use strict';
const request = require('supertest');
const app = require('./app.js');
var path = require('path');
var tape = require('tape');
var tapeNock = require('tape-nock');
// call tapeNock with tape and an options object
var test = tapeNock(tape, {
fixtures: path.join(__dirname, 'fixtures')
});
describe('Version test', function() {
this.timeout(0);
it('test version', function(done) {
test('record_version.json', function(t) {
request(app)
.get('/hammer/version')
.expect(200, {
url: "http://httpbin.org/get",
version: '0.1.0'
})
.end(function(err, res) {
if (err) return done(err);
t.end();
done();
});
});
});
});
The "package.json":
{
"name": "remote_node_test",
"version": "1.0.0",
"description": "",
"main": "app.js",
"dependencies": {
"express": "^4.14.0",
"mocha": "^3.2.0",
"nock": "^9.0.2",
"superagent": "^3.3.1",
"supertest": "^2.0.1",
"tape": "^4.6.3",
"tape-nock": "^1.4.0"
},
"devDependencies": {
"mocha": "^3.2.0"
},
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC"
}
The test are run with "mocha":
NOCK_BACK_MODE=record node_modules/mocha/bin/mocha
First run works, second run with "lockdown/record" does not work.
The error:
% NOCK_BACK_MODE=lockdown node_modules/mocha/bin/mocha test.js :(
Version test
TAP version 13
# details.json
1) return current version
0 passing (32ms)
1 failing
1) Version test return current version:
TypeError: Cannot read property 'status' of undefined
at Test._assertStatus (node_modules/supertest/lib/test.js:263:10)
at Test._assertFunction (node_modules/supertest/lib/test.js:281:11)
at Test.assert (node_modules/supertest/lib/test.js:171:18)
at Server.assert (node_modules/supertest/lib/test.js:131:12)
at emitCloseNT (net.js:1553:8)
at _combinedTickCallback (internal/process/next_tick.js:71:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
Recorded are all requests, but i need only to record the "external" requests, and prevent "mocking/recording" my internal logic.
If you're using mocha, you may want to look for a similar nock/nockBack helpers that are mocha-specific (https://www.npmjs.com/search?q=mocha+nock)
That being said, you may also run into problems where the HTTP call supertest makes to the app gets picked up by nockBack.
I made a little example that uses only tape to do what you're trying to accomplish:
https://github.com/Flet/tape-nock-with-supertest-example
The afterRecord and before functions defined in setup-tape-nock.js are probably the secret sauce you would need even if using some other nockBack mocha helper.
Hope this helps!
One solution seems "replay" and configuring "passThrough" of requests to my local app.
/* global describe, it */
'use strict';
const request = require('supertest');
const app = require('./app.js');
var path = require('path');
const Replay = require('replay');
Replay.fixtures = __dirname + '/fixtures/replay';
Replay.passThrough('localhost', '127.0.0.1', '0.0.0.0');
describe('Version test', function() {
this.timeout(0);
it('test version', function(done) {
request(app)
.get('/hammer/version')
.expect(200, {
url: "http://httpbin.org/get",
version: '0.1.0'
})
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});

Extracting POST parameters from request in Nodejs

I am trying to get parameters from a POST in the variable postData by using the request by -
( i used this because it was suggested here - How do I get the post request with express js? )
and here -
How to retrieve POST query parameters?
var express = require('express');
var app = express();
var fs = require('fs');
var json = require('json');
app.use(express.json()); // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies
app.post('/shrib/:file/:data',function(req,res){
var fileName = req.params.file;
var data = req.params.data;
req.on('data',function(data){ body+=data; } );
req.on('end' ,function(){
var postData = qs.parse(body);
var writeStream = fs.createWriteStream(fileName);
var postData = req.body.text;
if(postData)
console.log(postData);
else
console.log("failed miserably");
res.write(200);
res.end();
});
});
app.get('/shrib/:file',function(req,res){
var fileName = req.params.file;
if(fileName != ''){
var readStream = fs.createReadStream(fileName);
var content;
readStream.on('data',function(chunk){
content+=chunk.toString();
console.log(content);
});
readStream.on('end',function(){
res.writeHead(200,{"Content-Type":"text/html"});
res.write("<form id=\"submitForm\" method=\"POST\">");
res.write("<textarea id=\"text\"rows=50 cols=50 >");
console.log(content);
if(content)
res.write(content.toString());
res.write("</textarea>");
res.write("<input type=\"submit\" value=\"submit\" />");
res.write("</form>");
res.write("<script>");
res.write("var windowLocation = location.href;");
res.write("document.getElementById(\"submitForm\").action=windowLocation + \'/data\';");
res.write("</script>");
res.end();
});
}else{
res.writeHead(200);
res.write("invalid/empty path name");
}
});
app.listen(8080);
and got this error -
Error: Most middleware (like json) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
at Function.Object.defineProperty.get (/home/unknown/public_html/node/node_modules/express/lib/express.js:89:13)
I was using body parser before which i read in some solutions here and it gave me the same error middleware missing, i installed it globally then also got the same error and after that i read about json , so i installed it globally using
npm install -g json
did not work, then too. then i tried adding the dependancies -
{
"name": "express_shrib.js",
"version": "0.0.1",
"description": "Creating Shrib Using Express",
"main": "express_shrib.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/iamdeadman/nodejs.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/iamdeadman/nodejs/issues"
},
"homepage": "https://github.com/iamdeadman/nodejs",
"dependencies": {
"express": ">= 1.2.0",
"json": ">= 9.0.0"
}
}
and ran npm install
still the same error -
Error: Most middleware (like json) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
at Function.Object.defineProperty.get (/home/unknown/public_html/node/node_modules/express/lib/express.js:89:13)
Edit** - Code with the new body-parser module
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
app.use(bodyParser());
app.post('/shrib/:file/:data',function(req,res){
var fileName = req.params.file;
var data = req.params.data;
req.on('data',function(data){ body+=data; } );
req.on('end' ,function(){
var postData = req.body;
var writeStream = fs.createWriteStream(fileName);
if(postData)
console.log(postData);
else{
console.log("failed miserably");
console.log(postData);
}
res.writeHead(200);
res.end();
});
});
app.get('/shrib/:file',function(req,res){
var fileName = req.params.file;
if(fileName != ''){
var readStream = fs.createReadStream(fileName);
var content;
readStream.on('data',function(chunk){
content+=chunk.toString();
console.log(content);
});
readStream.on('end',function(){
res.writeHead(200,{"Content-Type":"text/html"});
res.write("<form id=\"submitForm\" method=\"POST\">");
res.write("<textarea id=\"text\"rows=50 cols=50 >");
console.log(content);
if(content)
res.write(content.toString());
res.write("</textarea>");
res.write("<input type=\"submit\" value=\"submit\" />");
res.write("</form>");
res.write("<script>");
res.write("var windowLocation = location.href;");
res.write("document.getElementById(\"submitForm\").action=windowLocation + \'/data\';");
res.write("</script>");
res.end();
});
}else{
res.writeHead(200);
res.write("invalid/empty path name");
}
});
app.listen(8080);
and here i get
{}
in the console which means that the body object is empty for some reason.
With Express 4, the body parsing middleware (like other previously built-in middleware) was extracted out into the 'body-parser' module. However, this new module only handles JSON and urlencoded form submissions, not multipart.
If you need multipart support, you'd need to use something like connect-busboy or multer or connect-multiparty (connect-multiparty is essentially the old Express bodyParser middleware).
EDIT: Also, the name attribute is missing for the textarea input field. This is required, otherwise the field will not be sent with the form.
When using express 4 use body-parser middleware to get parameters.
Multipart has issue that it creates loads of temp files. So its better to avoid it whenever possible and use upload services directly.
app.use(function (req, res, next) {
var urlParser = require('url');
var url = urlParser.parse(req.url, true);
if (url.pathname == "/rest/file/upload") {
next();
} else {
var contentType = req.header("content-type");
if (contentType && contentType.indexOf("application/json") != -1) {
bodyParser.json({limit: 1024 * 1024 * 10})(req, res, next);
} else {
bodyParser.urlencoded({ extended: true, limit: 1024 * 1024 * 10})(req, res, next);
}
}
});
then just get your request parameter as :
console.log(req.param("parameter-name"));

Categories