Issue with POST in Angular JS - angularjs

I am trying to POST data using angular+ node j to my REST service running in jetty.
Here is the code:
var app =
angular.module("loginapp", []);
app.controller("loginctrl", function($scope,$http) {
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
app.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['self', 'http://localhost:9011/**']);
}]);
$scope.login = function(e){
console.log('clicked login...');
e.preventDefault();
$http({
url: "http://localhost:9011/test/dummy/doStuff1",
method: "POST",
data : {email: $scope.email, password: $scope.password},
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' },
withCredentials: false,
}).success(function (data, status, headers, config) {
console.log('status',status);
console.log('data',JSON.stringify(data));
console.log('headers',headers);
});
}
});
However the data which i am passing in the Request is not getting mapped to the method argument in the REST service due to which the method is not getting invoked.Here is the code:
#Path("/test/dummy")
public class DummyService {
#POST
#Consumes({MediaType.APPLICATION_FORM_URLENCODED})
#Produces({ MediaType.APPLICATION_JSON})
#Path("/doStuff1")
public Response doStuff1(DummyParam param) {
System.out.println("Hiiiiiiiiii : ");
return Response.ok().build();
}
Without the param argument the method gets invoked however with it its not working.
The server file is :
var express = require("express");
var path = require("path");
var bodyParser = require("body-parser");
var cor = require("cors");
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cor());
app.all("/*", function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
if (req.method === 'OPTIONS') {
res.statusCode = 204;
return res.end();
} else {
return next();
}
});
app.get('/',function(req,res) {
res.sendFile(__dirname +'/test/test.html')
})
app.listen(3000);
console.log("Running at Port 3000");
Can anyone help me how to resolve this issue?
Thanks

If you see the from data coming correctly then it has to be something with setting bodyParser correctly, I had the same problem and solved it with bodyParser extension for json file. In Express.js it looks like this.
app.use(bodyParser.json());
My last guess is that maybe you need cookie-parser as well
Try to add it after body-parser:
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(cookieParser('SecretCode!'));
I still deepen my knowledge about express/node, but maybe it will help if not i suggest you to disconnect you api on small parts so it is easier to see what's wrong.

Related

Mean Stack: When using $http "Post" with Angular, req.body in Express contains additional {} and saving it to mongod does not work

I want to post data from Angular and save it in MongoDB through Express and Mongoose.
myConfig file
'use strict';
var express = require('express');
var parser = require('body-parser');
var router = require('./api');
var app = express();
require('./database');
app.use('/', express.static('public'));
app.use(parser.urlencoded({extended: true}));
app.use(parser.json());
app.use('/api', router);
app.listen(3000, function () {
console.log("Evalyst is running on port 3000");
});
myController
$scope.addNewEvaluation = function (newEvaluation) {
dataService.addNewEvaluation(newEvaluation);
$scope.closeModal();
};
MyService
$http({
method: 'POST',
url: 'http://localhost:3000/api/evaluations',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {'evaluation': newEvaluation}
}).success(function (data) {
console.log(data);
}).error(function(data){
console.log(data);
});
};
My backend (node.js, express, mongoose)
router.post('/evaluations', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
var evaluation = req.body;
console.log(evaluation);
Evaluation.create(evaluation, function (err, evaluation) {
if (err) {
return res.status(500).json({message: err.message});
}
res.json({evaluation, message: "Evaluation created"});
});
});
The problem is that an empty object is saved in my MongoDB.
In my req.body, I have the following line:
body: { '{"evaluation":{"title":"Sports","description":"Just do it","notifFreq":"daily"}}': '' },
I don't understand why I get the evaluation wrapped in {' }' : ''}.
Try to send it like this
$http({
method: 'POST',
url: 'http://localhost:3000/api/evaluations',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: newEvaluation
}).success(function (data) {
console.log(data);
}).error(function(data){
console.log(data);
});
because your newEvaluation is already an object.
Your newEvaluation data is a string.
'{"evaluation":{"title":"Sports","description":"Just do it","notifFreq":"daily"}}': ''
Please send javascript object to backend. Split your string first by ":" character and then parse json string to json object.
$scope.addNewEvaluation = function (newEvaluation) {
var splitStr = newEvaluation.split(":")[0],
newEvaluationObj = JSON.parse(splitStr);
dataService.addNewEvaluation(splitStr);
$scope.closeModal();
};

Angularjs cant send data from input to nodejs server, POST not found 404

Here are mistakes shown in console, i can't understand why http adress in is not found
POST http://localhost:3000/api/message 404 (Not Found) angular.min.js
XHR finished loading: POST "http://localhost:3000/api/message". angular.min.js
Error "Cannot POST /api/message\n" controllers.js
my controllerjs:
testControllers.controller('SecCtrl', ['$scope', '$http',
function SecCtrl($scope, $http) {
$scope.message = '';
$scope.saveInput = function() {
$http({
method: 'POST',
url: 'http://localhost:3000/api/message',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify({message: $scope.message})
}).
success(function(response) {
console.log("Success " + JSON.stringify(response));
}).
error(function(response) {
console.log("Error " + JSON.stringify(response));
});
};
}]);
server.js code, and after i send input data to server i try to save it into mongodb using mongoose:
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var Message = mongoose.model('Message', {
message: String
});
mongoose.connect('mongodb://localhost:27017/test', function(err) {
if(!err) {
console.log('connected to mongo');
}
});
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({'extended':'true'}));
app.use(bodyParser.json());
app.use(bodyParser.json({type: 'application/vnd.api+json'}));
app.use(function(res,req,next) {
res.header("Access-Control-Allow-Origin");
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
})
app.get('api/message', function(req,res) {
Message.find(function(err,message) {
if(err) {
res.send(err);
} else {
res.json(message);
}
})
})
app.post('api/message', function(req,res) {
var message = new Message(req.body);
message.save();
res.status(200);
})
app.get('/', function(req,res) {
res.sendFile(__dirname + '/index.html');
})
app.listen(3000);
console.log('listening on port 3000');
I think it should be with absolute path /api/message:
app.post('/api/message', function(req,res) {
var message = new Message(req.body);
message.save();
res.status(200);
});
Look at here http://expressjs.com/en/api.html#path-examples

Error: No 'Access-Control-Allow-Origin' header is present on the requested resource. Using expressjs and angular

I think so many people gave solution on it but none of them worked for me
Please check my code and tell me where I have gone wrong...
I deployed in heroku also still seeing the same issue
Angular JS snippet:
$http({
method: 'GET',
url: "https://api.forecast.io/forecast/2c56930e3e0117b9943b9f618acfe981/17.3434321,78.536526",
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
}).
success(function(status) {
$scope.weather = status.data;
}).
error(function(status) {
console.log("failure");
});
Expressjs(server) snippet:
var express = require('express'),
http = require('http');
var bodyParser = require('body-parser');
var jsonfile = require('jsonfile');
var path = require('path');
var cors = require('cors');
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'api.openweathermap.org');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
var app = express()
.use(bodyParser.urlencoded({
extended: true
}))
.use(bodyParser.json())
.use(express.static(__dirname + '/public'))
.use(cors())
.use(allowCrossDomain)
.use('/node_modules', express.static(__dirname + '/node_modules'))
.use('/bower_components', express.static(__dirname + '/bower_components'));
app.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();
});
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
app.all('/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
You dont need the "Access-Control-Allow-Origin" settings.
The problem is, that your are grabbing the url from the client side.
Just make a route with nodejs (maybe with express) to get the data from an extern server.
Than you can get your data through your nodejs route to show/use it on client side (angularjs).
Update:
Server side:
var express = require('express'),
http = require('http');
var bodyParser = require('body-parser');
var app = express();
var request = require('request');
app
// express json parser
.use(bodyParser.urlencoded({
extended: true
}))
.use(bodyParser.json())
// public foder for client side
.use(express.static(__dirname + '/public'))
// express route to get the forecast data/json
.get('/forecast', function(req, res) {
request({
url: "https://api.forecast.io/forecast/2c56930e3e0117b9943b9f618acfe981/17.3434321,78.536526"
}, function (error, response, body) {
res.send(response.body);
});
})
// server port
.listen(8080);
On Clientside you have to call now the url of your local route:
$http
.get("http://localhost:8080/forecast")
.success(function (data, status) {
$scope.weather = data;
})
.error(function (data, status) {
console.log("Request failed " + status);
})
.then(function() {
console.log($scope.weather);
});

Sending SMS via Twilio POST error

This comes after half a day of banging my head against the screen, so any help would be greatly appreciated.
I'm trying to send an SMS message via Twillio on a click-event. I'm using Angular, calling the SendTestMessage function on click. Unfortunately, I keep running into this error:
POST http://localhost:3000/sendsms 500 (Internal Server Error)
Here is my controller:
.controller('WhotoMessageCtrl', function($scope, UserService, $http, $q){
console.log("whotomessage page");
$scope.saveContactInfo = saveContactInfo;
$scope.contact = {};
$scope.sendTestMessage = sendTestMessage;
function sendTestMessage(number){
console.log('this fired', number);
var defer = $q.defer();
$http({
url: '/sendsms',
method: 'POST',
data: JSON.stringify({number}),
contentType: 'application/json',
}).success(function (number){
console.log('text has been sent to', number);
defer.resolve(user);
});
return defer.promise;
};
Here is my server side code:
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if ('OPTIONS' == req.method){
return res.send(200);
}
next();
});
app.use(function (req, res, next) {
var sendSMS = function(to){
var outgoing = {};
outgoing.to = to;
outgoing.from = '19725593683';
outgoing.body = 'Your table is ready';
client.messages.create(outgoing, function(error, message){
if (error){console.log(error.message)}
})
};
app.post('/sendsms', function(req, res){
sendResponse(res, req.body.phoneNo, 201)
sendSMS(req.body.phoneNo)
res.end();
});
Any suggestions?
Hey Twilio developer evangelist here.
It could have been that you forgot to copy bits of the code, but it seems client hasn't been defined, which means you aren't even making a request to Twilio.
The correct way to initialise client according to the documentation is:
// Your accountSid and authToken from twilio.com/user/account
var accountSid = '{{ account_sid }}';
var authToken = "{{ auth_token }}";
var client = require('twilio')(accountSid, authToken);
Only then you can on your code do:
var sendSMS = function(to){
var outgoing = {};
outgoing.to = to;
outgoing.from = '19725593683';
outgoing.body = 'Your table is ready';
client.messages.create(outgoing, function(error, message){
if (error){console.log(error.message)}
})
};
Hope this helps you!

Angular $http POST gets null from ExpressJS

I'm inexperienced in backend and working with Node and trying to set up an $http POST request to send a form to Express. Each time I make the request, my callback data is null. Perhaps my Express routes are not configured correctly? I'm using Angular to communicate with Express/Node to send an email through nodemailer (which I've already properly configured).
Here is my $http POST request:
client/service/emailer/emailer.js
angular.module('public').factory('EmailerService',function($http) {
return {
postEmail: function(emailData, callback) {
console.log('call http with object', emailData);
$http({
method: 'POST',
url: 'http://my-website.com/server/routes/emailer',
data: emailData,
headers: { "Content-Type": "application/json" },
responseType: 'json'
}).success(function(data, status, headers, config) {
console.log('success', data, status);
}).error(function(data, status, headers, config) {
console.log('error', data, status);
}).catch(function(error){
console.log('catch', error);
});
}
};
});
Here is my server side Express configuration:
server/routes/emailer.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var logger = require('morgan');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(logger('dev'));
app.post('/emailer', function(req,res) {
// NOTHING LOGS HERE
console.log(res, req, req.body, res.body);
});
module.exports = app;
Nothing logs to the console here, and the error handling on the $http request returns this:
emailer.js:4 call http with Object {email: "asdf"}
angular.js:8632 OPTIONS http://matt-mcdaniel.com/server/routes/emailer net::ERR_CONNECTION_TIMED_OUT(anonymous function) # angular.js:8632sendReq # angular.js:8426$get.serverRequest # angular.js:8146deferred.promise.then.wrappedCallback # angular.js:11682deferred.promise.then.wrappedCallback # angular.js:11682(anonymous function) # angular.js:11768$get.Scope.$eval # angular.js:12811$get.Scope.$digest # angular.js:12623$get.Scope.$apply # angular.js:12915(anonymous function) # angular.js:19264jQuery.event.dispatch # jquery.js:4676jQuery.event.add.elemData.handle # jquery.js:4360
emailer.js:14 error null 0
emailer.js:16 catch Object {data: null, status: 0, headers: function, config: Object, statusText: ""}
For good measure, and since I'm new to learning Express, I'll post my server side app.js.
server/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var compression = require('compression');
var routes = require('./routes/index');
var contact = require('./routes/emailer');
var app = express();
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(compression());
app.use(require('connect-livereload')({
port: 35729,
ignore: ['.js']
}));
/** Development Settings */
if (app.get('env') === 'development') {
// This will change in production since we'll be using the dist folder
app.use(express.static(path.join(__dirname, '../client')));
// This covers serving up the index page
// app.use(express.static(path.join(__dirname, '../client/.tmp')));
// app.use(express.static(path.join(__dirname, '../client/public')));
// Error Handling
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
/**
* Production Settings
*/
if (app.get('env') === 'production') {
// changes it to use the optimized version for production
app.use(express.static(path.join(__dirname, '/dist')));
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
}
module.exports = app;
app.use(function(req, res) {
res.sendfile(__dirname + '/dist/index.html');
});
Here is my file Structure:
You've definitely got some problems in your emailer.js route. You should only have routing logic there, you shouldn't be recreating your express app. Express gives you a Router object to make this easy. For example, your emailer.js could look like this:
module.exports = express.Router()
.post('/emailer', function(req,res) {
console.log(res, req, req.body, res.body);
res.json({hello:'world'});
});
And you can map this route in server/app.js like so:
var emailer = require('./routes/emailer');
// ...After all app.use statements, but *before* your error handlers
app.use('/server/routes', emailer);

Resources