Data undefined at Node.js from AngularJS POST request - javascript

I am attempting to send a fairly simple POST request to my server using AngularJS. The request goes through and hits my controller on the back end, but for some reason req.data is showing up as undefined.
Front End Controller:
function CardDirectiveController($http, $scope) {
var self = this;
self.addToFavorites = function() {
let card = {
id: $scope.$id,
attack : $scope.attack,
cost: $scope.cost,
img: $scope.img,
name: $scope.name,
class: $scope.class,
rarity: $scope.rarity,
type: $scope.type
}
return $http({
method: 'POST',
url: '/card',
data: card
})
};
}
angular.module('cardDirective').controller('CardDirectiveController', CardDirectiveController);
Server
'use strict';
let express = require('express'),
path = require('path'),
router = require('./routes/sampleRouter'),
cardRouter = require('./routes/cardRouter');
let app = express();
// Serve any requests for static files (like index.html)
app.use(express.static(path.join(__dirname + '/public/')));
// Use any routing rules found in the router file
app.use('/', router);
app.use('/card', cardRouter)
app.listen(PORT, function() {
console.log('Application live and running on port: ' + PORT);
});
Router:
'use strict';
let express = require('express'),
cardController = require('./../controllers/cardController');
let router = express.Router();
router.route('/').post(cardController.postCard);
router.route('/:cardName').get(cardController.showCards);
module.exports = router;
Back End Controller
'use strict';
let cardController = {
showCards: showCards,
postCard: postCard
};
module.exports = cardController
function showCards(req, res) {
console.log('showCards ', req.params.cardName);
res.end()
}
function postCard(req, res) {
console.log('postCard ', req.url, req.method, req.data)
res.end()
}
The response I am getting in the console from making this request is postCard / POST undefined. Console logging the card object returns the expected result. I feel like I must be missing something obvious, but I've been stuck for a while now.

You need to use bodyParser middleware to parse request body.
Install the body-parser module:
$ npm install body-parser
Configure it in app.js :
var bodyParser = require('body-parser');
// parse application/json
app.use(bodyParser.json());
In your controller use req.body instead of req.data:
function postCard(req, res) {
console.log('postCard ', req.url, req.method, req.body);
res.end();
}

Please use body-parser in your app.js file.
Change your server.js file to following code
'use strict';
let express = require('express'),
path = require('path'),
router = require('./routes/sampleRouter'),
cardRouter = require('./routes/cardRouter'),
bodyParser = require('body-parser');
let app = express();
// Serve any requests for static files (like index.html)
app.use(express.static(path.join(__dirname + '/public/')));
// parse application/json
app.use(bodyParser.json());
// Use any routing rules found in the router file
app.use('/', router);
app.use('/card', cardRouter)
app.listen(PORT, function() {
console.log('Application live and running on port: ' + PORT);
});

Related

I got the error : Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script

I'm trying to register a service worker to a html page and I get the error from title.
I'm working on linux,I have the right to write,delete,modify and so on,(I'm on # ).
I'm on a path like :
/var/www/a/b/c/d/e/f/project
And here I have a node.js server(index.js) , the html page(index.html) and the service worker(ServiceWorker.js)
The node.js server looks like:
const https = require('https');
const fs = require('fs');
var path = require('path');
const express = require('express');
const app = express();
const router = express.Router();
const pool = require('./mysqldb.js');
const pathView = __dirname + "/views/";
const IMGPath = "/public";
var bodyParser = require("body-parser");
const listenPort = 8010;
// Process application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// Process application/json
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use('/public', express.static('public'));
// This route will be used to print the type of HTTP request the particular
Route is referring to
router.use(function (req, res, next) {
next();
});
app.engine('html', require('ejs').renderFile);
app.get('/index.html',function(req,res){
res.render('/var/www/a/b/c/d/e/f/project/index.html');
});
app.use( "/", router);
// Not found
app.use("*",function(req,res){
res.setHeader('Content-Type', 'text/html');
res.status(404).send('Page introuvable !');
});
// Run server
app.listen(listenPort, function () {
console.log( listenPort )
});
//HTTPS
https.createServer(options, app).listen(8000);
And the .html file looks like:
<html>
<body>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('ServiceWorker.js', {
scope: './'
}).then(function (registration) {
var serviceWorker;
if (registration.installing) {
serviceWorker = registration.installing;
document.querySelector('#kind').textContent = 'installing';
} else if (registration.waiting) {
serviceWorker = registration.waiting;
document.querySelector('#kind').textContent = 'waiting';
} else if (registration.active) {
serviceWorker = registration.active;
document.querySelector('#kind').textContent = 'active';
}
if (serviceWorker) {
// logState(serviceWorker.state);
serviceWorker.addEventListener('statechange', function (e) {
// logState(e.target.state);
});
}
}).catch (function (error) {
// Something went wrong during registration. The service-worker.js file
// might be unavailable or contain a syntax error.
console.log('Service Worker registration error : ' , error);
});
} else {
console.log('Please update your brower!');
// The current browser doesn't support service workers.
}
</script>
</body>
</html>
I run the index.js node( command : "node index.js")
Everything is fine,the page is loading(I mean the script from the page) and i get the following error:
Service Worker registration error : TypeError: Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script.
And I don't know what to do.I basically have the ServiceWorker.js,index.html and index.js in the same folder.I try to run them but somehow the path is wrong...
Can someone help me?
Include this in your app.js and put your service worker in your public directory/folder.
app.get("/ServiceWorker.js", (req, res) => {
res.sendFile(path.resolve(__dirname, "public", "ServiceWorker.js"));
});

redirect to different controller dependant on Url

Ok so I'm trying to redirect the request to a different controller depending on the URL.
My server.js :
const express = require('express');
var app = express();
var router = express.Router();
// controllers
var { loginController } = require('./controller/loginController');
// Specify routes
app.use('/test', loginController);
app.listen(3000, () => {
console.log('started on port 3000');
});
module.exports = { app }
Now if the URL is /test then I would like to redirect the request to loginController, inside loginController I have the following:
const express = require('express');
var router = express.Router();
router.get('/', (req, res) => {
res.send('inside logincontroller');
});
Very short and sweet, however when I run node server.js I get the following error message: Router.use() requires middleware function but got a undefined now I've gone through the Router Use but I'm slightly confused (newbie) I don't have any middleware at present.
Would someone be able to explain to me how I go about redirecting the request to the loginController when the url is /test
server.js
const express = require('express')
// Controllers
var loginController = require('./controller/loginController')
var app = express()
// Specify routes
app.use('/test', loginController)
app.listen(3000, () => {
console.log('started on port 3000')
})
loginController.js
const express = require('express')
var router = express.Router()
router.get('/', (req, res) => {
res.send('inside logincontroller')
})
module.exports = router
Then if you visit http://localhost:3000/test will get the output 'inside logincontroller'

Node in Corporative Environment with NODESSPI

I developed a NODE API to serve data to Angular app. The original idea is to use NODESSPI for integrated authentication as we plan to run this on a corporative environment. CORS will be needed as the API Node will be hosted on a different domain.
I'm struggling to use NODESSPI for integrated authentication of the $HTTP requests.
To test it on my computer I've created a simple js file to instantiate a node server with express to run my angular app (I know it could be done without express, but it was faster to implement). It is running on Port 5001.
'use strict';
var express = require('express');
var http = require('http');
var path = require('path');
var morgan = require('morgan');
var errorhandler = require('errorhandler');
var app = express();
// all environments
app.set('port', process.env.PORT || 5001);
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.use(morgan('dev'));
// serve up static assets
app.use(express.static(path.join(__dirname, 'app')));
// development only
if ('development' === app.get('env')) {
app.use(errorhandler());
}
console.log('trying to start server...', path.join(__dirname, 'app'));
http.createServer(app).listen(app.get('port'), function () {
console.log('App server listening on port ' + app.get('port'));
});
My Angular code is on very early stage as its purpose is just prove the concept. Note I'm not specifying any kind of headers on my $http get.
main.controller.js
'use strict';
monthApp.controller('mainPageCtrl',
function mainPageCtrl($scope, $rootScope, $location, $rootElement, $q, $http) {
console.log("mainPageCtrl is in control");
$http({
url: 'http://localhost:3000/api/',
methof: 'GET'
})
.then(function(data){
console.log(data);
})
.catch(function(error){
console.log(error);
})
});
To run my NODE API simulating the server side, I'm also using Express and running it at the port 3000, here is the code:
//Lib Dependecies
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var sql = require("seriate");
var cors = require("cors");
var express = require("express");
var path = require("path");
var Q = require("q");
var oracle = require("oracledb");
var restClient = require("node-rest-client").Client;
var nodeSSPI = require('node-sspi');
var ActiveDirectory = require("activedirectory");
//API Custom Modules Dependecies
var reservoirApi = require("./reservoirApi");
var ldapApi = require("./ldapApi");
var energyApi = require("./energyApi");
var PIApi = require("./PIApi");
//Express config
var app = express();
app.use ( cors() );
app.options('*', cors() );
app.use ( bodyParser.json() );
app.use ( bodyParser.urlencoded( {extended: true} ) );
app.use ( cookieParser() );
app.use ( express.static( __dirname + '/public') );
//Server config
var serverConfig = {port: 3000};
//Sql server config
var config = {
"server":"myserver",
"user":"myuser",
"password":"mypass",
"database":"mydatabase"
};
sql.setDefaultConfig(config);
//Setup endpoint routes
var router = express.Router();
//Basic Router Config
router.use(function(req, res, next){
//Integrated Authentication for Windows
var nodeSSPIObj = new nodeSSPI({
retrieveGroups: true
});
try{
nodeSSPIObj.authenticate(req, res, function(err){
res.finished || next();
});
}
catch(err)
{
res.status(500).send(JSON.stringify({status: 500, message: "URL mal formatada, verifique sua requisição HTTP", detail: err.message}));
}
});
router.get('/', function(req, res){
res.json({Message: 'Data Access API.', AuthUser: req.connection.user, AuthUserGroups: req.connection.userGroups });
});
app.use('/api', router);
//Modules End-Point registration
reservoirApi.register(router);
ldapApi.register(router);
energyApi.register(router);
PIApi.register(router);
//Start Server
app.listen(serverConfig.port);
console.log("SOA API Listening port at " + serverConfig.port)
The results are:
When using Chrome to reach the address: http://localhost:3000/api this works just fine. It detects my user account and return all windows groups I'm part of.
When running my angular code it returns:
Object {data: "", status: 401, config: Object, statusText: "Unauthorized"}
When testing with Postman it also works (with authorization type = 'No Auth')
When removing all NodeSSPI code from my Routers, I can receive data (I've tested with other endpoints on my angular app) so CORS is properly set at the server side.
Is there anything I'm missing on the Angular side? I'm struggling to move forward from here. Appreciate any help.
Ok, I finally got this working. The changes needed as follow:
At the client Angular app
You need to set withCredentials to true on $http requests.
$http({
url: 'http://localhost:3000/api',
method: 'GET',
withCredentials: true,
headers : {
'Content-Type' : 'application/json',
}
})
At the node server
Some response headers are needed in the response. Origin cannot be '*' and you need to allow credentials. If you need to allow dynamic origins you can find a way of doing it in the CORS documentation.
//Cors options
var corsOptions = {
origin: 'http://localhost:5001',
optionsSuccessStatus: 200,
credentials: true,
}
//Express config
var app = express();
app.use ( cors(corsOptions) );
app.use ( bodyParser.json() );
app.use ( bodyParser.urlencoded( {extended: true} ) );
app.use ( cookieParser() );
app.use ( express.static( __dirname + '/public') );

How to use express middleware to handle all routes?

I have issue setting up routes for user in below code, I want to use express middleware and trying routes using app.use.
index.js is invoking user controller method once api's is being called So in below code i am trying to post data api/users from client but it returns 404.
How can i fix this issue using below routes setup ?
server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var mongoose = require('mongoose');
console.log(mongoose.connection.readyState);
var db = require('./config/db');
var port = process.env.PORT || 8080;
mongoose.connect(db.url);
app.use(methodOverride('X-HTTP-Method-Override'));
app.use(express.static(__dirname + '/public'));
require('./app/routes')(app); // configure our routes
require('./config/express')(app);
app.listen(port);
console.log('listening on port ' + port);
exports = module.exports = app;
app > routes.js
module.exports = function(app) {
app.use('api/users', require('./api/user'));
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // load our public/index.html file
// res.sendFile(path.join(__dirname, ''../public/views/index.html''));
});
};
config > express.js
var express = require('express');
var morgan = require('morgan');
var bodyParser = require('body-parser');
// import cookieParser from 'cookie-parser';
// import errorHandler from 'errorhandler';
var path = require('path');
// import lusca from 'lusca';
var config = require('./db');
var mongoose = require('mongoose');
//var mongoStore = connectMongo(session);
module.exports = function(app) {
// app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
}
User index where i will handle all crud operation for user
app > api > user > index.js
var express = require('express');
var controller = require('./user.controller');
var router = express.Router();
router.get('/', controller.index);
router.post('/',controller.create);
module.exports = router;
1st:
To handle all request
Bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions, where METHOD is the HTTP method of the request that the middleware function handles (such as GET, PUT, or POST) in lowercase.
This example shows a middleware function with no mount path. The function is executed every time the app receives a request.
app.use(function(req,res)
{
res.sendfile('./public/views/index.html');
console.log("Not found....I will handle *unhandle* rout here for you");
})
// app.get('*', function(req, res) use the above function instead of this
But this function at the end so it will only excute when no route path found to the app object.
Express documentation
2nd:
To handle createuser
var express = require('express');
var controller = require('./user.controller');
var router = express.Router();
// you must define route which you want to handle in user file
router.get('/api/user', controller.index);
router.post('/',controller.create);
module.exports = router;
Update working example with some explanation
Your app.js file
var express=require('express')
var app=express()
app.use('api/user',require('./user'))
app.use('/',require('./user'))
app.use(function(req,res)
{
res.sendfile('stack10.html')
console.log("Not found....I will handle *unhandle* rout here for you");
})
app.listen(8080,function()
{
console.log("server listening on port 8080")
})
user.js
var express = require('express')
var router = express.Router()
var app=express()
router.get('/api/user', function(req, res) {
res.send('respond for ..../api/user')
});
router.get('/',function (req,res) {
res.send('respose for ..../')
})
module.exports = router;
Your app.use will be app.use(api/user) while in user will be router.get(/api/user) so when u try http://127.0.0.1:8080/api/user
your response will be respond for ..../api/user

Node.js browser error Cannot GET/

I'm quite new to Node, I've been following a tutorial to build a simple server that serves dynamic pags with some basic routes but keep getting the Error: Cannot GET/ after running node server.js and calling localhost:3300 on the browser. My routes are defined externally and initialized using a routes.initialise() as follows:
//routes.js
var home = require('../controllers/home'),
image = require('../controllers/image'),
express = require('express');
module.exports.initialize = function(app, router) {
//var router = express.Router();
router.get('/', home.index);
router.get('/images/:image_id', image.index);
router.post('/images', image.create);
router.post('/images/:image_id/like', image.like);
router.post('/images/:image_id/comment', image.comment);
app.use('/', router);
};
I've searched far and wide but no solution forthcoming. I'm really frustrated and will need some help here.
I have a server.js that creates the server:
//server.js
var express = require('express'),
config = require('./server/configure'),
app = express();
app.set('port', process.env.PORT || 3300);
app.set('views', __dirname + '/views');
app = config(app);
var server = app.listen(app.get('port'), function() {
console.log('Server up: http://localhost:' + app.get('port'));
});
and a configure.js that configures the server:
//configure.js
var path = require('path'),
routes = require('./routes'),
exphbs = require('express3-handlebars'),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
morgan = require('morgan'),
methodOverride = require('method-override'),
errorHandler = require('errorhandler');
module.exports = function(app) {
app.engine('handlebars', exphbs.create({
defaultLayout: 'main',
layoutsDir: app.get('views') + '/layouts',
partialsDir: [app.get('views') + '/partials']
}).engine);
app.set('view engine', 'handlebars');
app.use(morgan('dev'));
app.use(bodyParser({
uploadDir:path.join(__dirname, 'public/upload/temp')
}));
app.use(methodOverride());
app.use(cookieParser('some-secret-value-here'));
routes.initialize(app, new express.Router());
app.use('/public/', express.static(path.join(__dirname, '../public')));
if ('development' === app.get('env')) {
app.use(errorHandler());
}
return app;
};
also two files, home.js and image.js which are supposed to provide the default routes from configure.js:
//home.js
module.exports = {
index: function(req, res) {
res.send('The home:index controller');
}
};
//image.js
module.exports = {
index: function(req, res) {
res.send('The image:index controller ' + req.params.image_id);
},
create: function(req, res) {
res.send('The image:create POST controller');
},
like: function(req, res) {
res.send('The image:like POST controller');
},
comment: function(req, res) {
res.send('The image:comment POST controller');
}
};
Anytime I try to GET any of the links on the browser it returns the Cannot GET/ error. Any help will be greatly appreciated.
Thank you so much :)
I actually copied your exact code and it worked as you expect, though frankly it's got a bunch of indirection and at least one deprecated module. Maybe you have a PORT environmental variable set, and so the app isn't actually running on 3300?

Categories