I would send data from angular to Express.
in my service ;
sendtext(text): Observable<any> {
console.log(text);
return this.http.post<string>(this.url, text, httpOptions);
}
I configure headers
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded'
})
my console.log(text) prints me the right text typed in an input.
In my server side I have created my server.js file
var http = require("http");
var admin = require('firebase-admin');
var firebase = require("firebase");
var express = require("express");
var app = express();
var routerProj = require("./routes/routes");
var bodyParser = require("body-parser");
var port = process.env.app_port || 8080; // set our port
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var server = app.listen(port);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,*");
next();
});
var config = {
......configuration...
};
firebase.initializeApp(config);
var serviceAccount = require("./ServiceAcountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://datatable-18f93.firebaseio.com"
});
app.use("/v1", routerProj);
//Create HTTP server and listen on port 8000 for requests
// Print URL for accessing server
console.log("Server running at http://127.0.0.1:8080/");
And I have created my router file:
var express = require("express"); // call express
var router = express.Router(); // get an instance of the express Router
var admin = require("firebase-admin");
router
.route("/")
.post(function (req, res, err) {
console.log(req.body);
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.push(
{
"text": req.body
}
);
});
module.exports = router;
Here console.log(req.body) prints an empty object {}
Is it because of the headers ? if yes how can I configure them ? I have already tried'Content-Type': 'application/json', and without headers, no result.
Related
I cannot fetch POST requests to my Express router. I have many GET requests which work fine, but this is my first POST request and it is not working.
My frontend code looks like this:
export async function postHamster(name, age) {
try {
await fetch('/hamsters/api/new-hamster',
{
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: name,
age: age
})
})
console.log("postHamster has run") //LOGGED
}
catch (e) {
console.error(e)
}
}
The response will always be:
fetchData.js:38 POST http://localhost:3000/hamsters/api/new-hamster 404 (Not Found)
I have triple-checked the path and it cannot be in error. The backend path is "router.get('api/new-hamster', async (req, res)..." in the file 'hamsters.js'.
I have also put the backend function at the very top of its file, to ensure that it is not overrruled by any other function in the file.
This is my server.js:
// THIS FIRST FUNCTION I JUST COPIED FROM A SOLUTION BUT IT DOES NOT SEEM TO HELP
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
server.route('/hamsters/api/new-hamster')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
});
return router;
}
const express = require('express');
const server = express();
const serverPort = process.env.PORT || 1234;
server.use(express.static(__dirname + '/../build'))
let data = require('./data.json')
const { Router } = require('express');
let router = new Router();
//USE BODY-PARSER BEFORE REGISTERING ROUTES!
const bodyParser = require('body-parser')
server.use(bodyParser.urlencoded({ extended: true }));
server.use(bodyParser.json())
server.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// ROUTES
const hamstersRoute = require('./routes/hamsters');
const chartsRoute = require('./routes/charts')
const gamesRoute = require('./routes/games')
const statsRoute = require('./routes/stats')
const imagesRoute = require('./routes/images')
const uploadRoute = require('./routes/upload')
server.use('/assets', express.static("assets"))
server.use(express.static('public'))
server.use('/hamsters', hamstersRoute)
server.use('/charts', chartsRoute)
server.use('/games', gamesRoute)
server.use('/stats', statsRoute)
server.use('/images', imagesRoute)
server.use('/upload', uploadRoute)
server.listen(serverPort, () => {
console.log(`Server is up n running on port ${serverPort}!`)
})
module.exports = data;
I have looked at these threads:
Cannot GET/POST with express Router()
Express.js routers post request returns 404
Express: router cannot read POST request
Have you checked the url you're trying to post to in the network tab in the console? I think you need to add a / before api in the backend route: router.get('/api/new-hamster', async (req, res)...".
You have this:
server.use(bodyParser.urlencoded({ extended: true }));
Instead of this:
server.use(bodyParser.urlencoded({ extended: false }));
I would update my client side view every insert in the database.
In y angular application I have a function that adds text to database :
ajoutText(newtext: String) {
this.dataService.sendtext(newtext)
.subscribe(res => this.socket.emit('save-message', { data: "hello" }));
}
after posting message to database I emit a socket. the idea is to trigger a get route to update my observable in Angular side with the new data, and create a data stream.
Here's my server configuration :
server.js:
var http = require("http");
var admin = require('firebase-admin');
var firebase = require("firebase");
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var port = process.env.app_port || 8080; // set our port
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var server = app.listen(port);
var io = require("socket.io")(server);
var routerProj = require("./routes/routes");
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,*");
next();
});
var config = {
... configuration...
};
firebase.initializeApp(config);
var serviceAccount = require("./ServiceAcountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://datatable-18f93.firebaseio.com"
});
app.use(function (req, res, next) {
req.io = io; // pass socket to route
next();
});
app.use("/v1", routerProj);
and routes.js file :
var express = require("express"); // call express
var router = express.Router(); // get an instance of the express Router
var admin = require("firebase-admin");
//module.exports = function (req) {
//router.route("/")
router.use(function (req, res, next) {
// Test
console.log(req.io.sockets)
next();
});
router
.route("/")
.get(function (req, res, err) {
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.once("value", function (snapshot) {
var list = [];
snapshot.forEach(function (elem) {
list.push(elem.val());
})
list = JSON.stringify(list);
res.send(list);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
res.status(500).send(errorObject.code);
});
});
router
.route("/")
.post(function (req, res, err) {
console.log(req.body);
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.push(
{
"text": req.body.text
}
);
});
//return router;
//}
module.exports = router;
How can I run post route on save-message emit from client side ?
I would use socket.io in my routes file.
I have found multiple methods but no one worked for me.
Now I'm trying this solution
var http = require("http");
var admin = require('firebase-admin');
var firebase = require("firebase");
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var port = process.env.app_port || 8080; // set our port
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var server = app.listen(port);
var io = require("socket.io")(server);
var routerProj = require("./routes/routes")(io);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,*");
next();
});
var config = {
XXX
};
firebase.initializeApp(config);
var serviceAccount = require("./ServiceAcountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://datatable-18f93.firebaseio.com"
});
app.use("/v1", routerProj);
//Create HTTP server and listen on port 8000 for requests
// Print URL for accessing server
console.log("Server running at http://127.0.0.1:8080/");
io.sockets.on("connection", function (socket) {
console.log("a user is connected");
});
Routes.js
var express = require("express"); // call express
var router = express.Router(); // get an instance of the express Router
var admin = require("firebase-admin");
module.exports = function (io) {
/*router.use(function (req, res, next) {
// do logging
io.on('connection', function (socket) {
console.log('User has connected to Index');
});
});*/
router.use(function (req, res, next) {
io.on('save-message', function (socket) {
console.log('User has connected to Index');
});
});
router
.route("/")
.get(function (req, res, err) {
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.once("value", function (snapshot) {
var list = [];
snapshot.forEach(function (elem) {
list.push(elem.val());
})
list = JSON.stringify(list);
//list = JSON.parse(list)
//console.log(JSON.stringify(list))
res.send(list);
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
res.status(500).send(errorObject.code);
});
});
router
.route("/")
.post(function (req, res, err) {
console.log(req.body);
// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("/");
// Attach an asynchronous callback to read the data at our posts reference
ref.push(
{
"text": req.body.text
}
);
});
return router
}
sockets are working in my server.js file , in console I get the message :"a user is connected" when I run my angular app.
But in my browser I run http://127.0.0.1:8080/v1in router.js console.log is not working, so sockets is not getting passed.
I have tried to emit an event :
ngOnInit() {
this.socket.emit('save-message', { room: "hello" });
}
In my router.js :
router.use(function (req, res, next) {
io.on('save-message', function (socket) {
console.log('User has connected to Index');
});
});
console.log don't print anything.
I have the following file: (auth.js)
module.exports = function (express, mongoose, router) {
router.route('/setup')
.get(function (req, res) {
var salt = bcrypt.genSaltSync(10);
var hashed = bcrypt.hashSync(req.query.password, salt);
// create a sample user
mongoose.models.playlist.create({username: 'Hieratic', password: hashed}, function (err, item) {
if (err) throw err;
console.log('User saved successfully');
res.json({ success: true });
});
});
return router;
};
And the current server file: (server.js)
"use strict";
var url = require('url');
var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs');
var crypto = require('crypto');
//npm install request
var request = require('request');
var config = require('./config/access.json');
var admin = require("firebase-admin");
var fireBaseConfig = require('./config/firebase.config.json');
var mongoose = require('mongoose');
var MongoClient = require('mongodb').MongoClient;
var mongodbConfig = require('./config/database.json');
var exec = require('child-process-promise').exec;
var app = express();
/**
* Schemas
*/
var UserModel = require('./schemas/user.schema.js')(mongoose);
var PlayListModel = require('./schemas/playlist.schema.js')(mongoose);
app.use(function (req, res, next) {
// CORS headers
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, x-access-token, Cache-Control, Pragma"
);
next();
});
var router = express.Router();
app.use(bodyParser.json({limit: '4mb'}));
app.use(bodyParser.urlencoded({
extended: true,
limit: '4mb'
}));
if (mongodbConfig.username && mongodbConfig.password) {
mongoose.connect(`mongodb://${mongodbConfig.username}:${mongodbConfig.password}#${mongodbConfig.host}:${mongodbConfig.port}/${mongodbConfig.database}`);
}
else {
mongoose.connect(`mongodb://${mongodbConfig.host}:${mongodbConfig.port}/${mongodbConfig.database}`);
}
process.on('disconnect', function () {
// If mongodb connection is not terminated child process never dies
mongoose.disconnect();
});
require('./auth.js')(express, mongoose, router);
var port = 51000;
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
When i attempt to access the /setup route it does hit the server however it throws an html page:
(http://localhost:51000/setup):
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /setup</pre>
</body>
Can anyone see what ive done wrong?
You have created router, but not registered it as a middleware:
var router = express.Router();
require('./auth.js')(express, mongoose, router);
app.use(router);
Refer to Cannot GET / Nodejs Error
You have no route set up.
Serve your page like this:
app.get('/', function (req, res) {
res.render('index', {});
});
var search = 1 + req.url.indexOf('?'); throws an error saying the statement to my left is undefined. Im using passportjs to create a login/registration page on my angular frontend. trying to make a post request to nodejs results in the above error. Im entirely new to the mean stack and ive tried several different tutorials to get myself up and running but have had some road blocks. can someone point in the right direction?
I've played around with just about every file moving around code and trying different solutions but nothing works, or one problem is solved but another occurs.
server.js
// set up ========================
var DATABASE = "mongodb://localhost:27017/smartHomeDevices";
var express = require("express");
var mongoose = require("mongoose"); //require monogDB Driver
var morgan = require("morgan"); // log requests to the console (express4)
var bodyParser = require("body-parser"); // pull information from HTML POST (express4)
var methodOverride = require("method-override"); // simulate DELETE and PUT (express4)
var passport = require("passport");
//var _ = require("lodash");
var http = require('http');
//setup
//app.models =
require("./Models/moduleIndex");
// Bring in the Passport config after model is defined
require('./config/passport');
//registering routes
var routes = require("./routes");
//Create App
var app = express();
app.use(passport.initialize());
//Add Middleware for REST API
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json);
app.use(bodyParser.json({
type: 'application/vnd.api+json'
}));
app.use(methodOverride("X-HTTP-Method-Override"));
app.use(morgan("dev"));
//CORS Support, makes API Public
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,");
res.header("Access-Control-Allow-Headers", "Content-Type,Authorization");
next();
});
app.use("/", routes);
// Connect to the db
mongoose.connect(DATABASE);
mongoose.connection.once("open", function() {
var serv = http.createServer(function(req, res) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end();
console.log(routes(req.method, req.url));
}).listen(3000);
//module.exports = app;
console.log("Listening on 3000");
});
routes.js
//setup
var express = require('express');
var router = express.Router();
var jwt = require('express-jwt');
var auth = jwt({
secret: 'MY_SECRET',
userProperty: 'payload'
});
var ctrlProfile = require('./Controllers/ProfileController');
var ctrlAuth = require('./Controllers/RegisterUserController');
// profile
router.get('/profile', auth, ctrlProfile.profileRead);
// authentication
router.post('/register', ctrlAuth.register);
router.post('/login', ctrlAuth.login);
module.exports = router;
/*module.exports = {
"/smartDevices" : require("./Controllers/SmartDeviceController"),
"/registeredUsers": require("./Controllers/RegisterUserController")
};*/
resgisteredUsersControllers.js
//setup
//var Resource = require("resourcejs");
var restful = require("node-restful");
var passport = require('passport');
var mongoose = require('mongoose');
var User = mongoose.model('registeredUserModel');
var sendJSONresponse = function(res, status, content) {
res.status(status);
res.json(content);
};
module.exports.register = function(req,res) {
console.log(req);
console.log("nw logging res");
console.log(res);
var user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.username = req.body.username;
user.setPassword(req.body.password);
user.save(function(err) {
if(err)
console.log(err);
var token;
token = user.generateJwt();
res.status(200);
res.json({
"token" : token
});
});
next();
};
module.exports.login = function(req, res) {
passport.authenticate('local', function(err, user, info) {
var token;
// If Passport throws/catches an error
if (err) {
res.status(404).json(err);
return;
}
// If a user is found
if (user) {
token = user.generateJwt();
res.status(200);
res.json({
"token": token
});
} else {
// If user is not found
res.status(401).json(info);
}
})(req, res);
next();
};
/*module.exports = function(app, route) {
//setup controller for restful
// Resource(app,"",route,app.models.registeredUserModel).rest();
var rest = restful.model("registeredUserModel",
app.models.registeredUserModel
).methods(["get", "put", "post", "delete"]);
rest.register(app, route);
//return Middleware
return function(req, res, next) {
next();
};
};
*/
ProfileController.js
var mongoose = require('mongoose');
var User = mongoose.model('registeredUserModel');
module.exports.profileRead = function(req, res) {
// If no user ID exists in the JWT return a 401
if (!req.payload._id) {
res.status(401).json({
"message" : "UnauthorizedError: private profile"
});
} else {
// Otherwise continue
User
.findById(req.payload._id)
.exec(function(err, user) {
res.status(200).json(user);
});
}
};
Request object does not have url field.