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!
Related
I wrote backend API on Node.js and Express.js v4, this part (index.js):
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://example.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post('/add1', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
app.put('/add2', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
app.get('/add3', function (req, res) {
db.one("INSERT INTO table(value1) VALUES (${value1}) RETURNING ID", req.query).then(function (data) {
res.json(data);
}).catch(function (error) {
res.json(error);
});
});
And I have Angular JS or sample ajax like this
app.controller('globalController', function($scope, $http) {
var jsd = {};
jsd.value1=1;
$http.put(API_URL + 'add2', jsd).then(function(data) {
console.log(data);
}, function(data) {
console.log(data);
});
});
and
$.ajax({
url: API_URL + 'add1',
method: 'POST',
dataType: 'json',
data: jsond,
success: function(data) {
console.log(data);
},
error: function(data) {
console.log(data);
}
});
But I don't recive any data to my req.query and in generally in req object. When I make my AJAX request to add3 with get, then all works, req.query has my params.
I read about this solution:
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
};
$httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});
and solution here
var multer = require("multer");
//...
var upload = multer({ dest: "./upload/" });
app.post("/post", upload.array(), function(req, res) {
console.log(req.body);
res.send(null);
}
I tried first, not works, and second is too strange solution (I can't save data to files and etc.) I think problem was in fist OPTION request, but I googled it, not found solution. I need little example (working code) how I can send POST or PUT data from Angular $http or AJAX and use this data in req object in node.js. In GET requests all this works, but how I can make it work on others?
Which version of Express are you using? It's possible that you're writing the old way and using the new version.
You might wanna check this out -- How to retrieve POST query parameters?
Anyway, I'd suggest you use ngResource for making REST HTTP calls in Angular.
Instantiate the Factory
This will expose a few methods e.g query, save etc.
angular
.module('MyModule')
.factory('AddEndpoint', AddEndpoint);
AddEndpoint.$inject = ['$resource'];
function AddEndpoint($resource) {
return $resource(API_URL + '/:param', { param: '#param' });
}
Enjoy The Factory
angular
.module('MyModule')
.controller('MyController', MyCtrl)
MyCtrl.$inject = ['AddEndpoint'];
function MyCtrl(AddEndpoint) {
var scope = this;
scope.getFromApi = AddEndpoint.get({ params: 'add1' }); // GET 'API_URL/add1'
scope.postToApi = postToApi;
function postToApi(data) {
data.params: 'add2'
AddEndpoint.save(data); // POST to 'API_URL/add2'
}
}
I'm learning Nodejs and ExpressJS. I'm trying to use ExpressJS and 2 Node modules (request-ip and geoip2) to get the client IP address for geolocation and then outputting the geolocation in the browser using AngularJS (1.x).
So far for my Nodejs and Expressjs code I have
var express = require('express');
// require request-ip and register it as middleware
var requestIp = require('request-ip');
// to convert the ip into geolocation coords
var geoip2 = require('geoip2');
// Init app
var app = express();
var port = process.env.PORT || 8000;
geoip2.init(); // init the db
//app.use(requestIp.mw({ attributeName: 'myCustomAttributeName'}));
var ip = '207.97.227.239';//67.183.57.64, 207.97.227.239
// respond to homepage req
app.get('/', function (req, res, next) {
//var ip = req.myCustomAttributeName;// use this for live
//var ip = '207.97.227.239';/* use this for testing */
console.log('requestIP is ' + ip);
next();
// geolocation
geoip2.lookupSimple(ip, function(error, result) {
if (error) {
console.log("Error: %s", error);
}
else if (result) {
console.log(result);//ipType was causing console.log duplication, IDK why
}
});
});
// set static folder
app.use('/', express.static(__dirname + '/public'));
app.listen(port, function(){
console.log('user location app is running');
});
And for Angular I have
angular.module('UserLocation', []);
angular.module('UserLocation')
.controller('MainController', MainController);
MainController.$inject = ['$http'];
function MainController($http) {
var vm = this;
vm.result = '';
vm.message = 'Hello World';
vm.getLocation = function() {
console.log();
return $http.get('localhost:8000', {
params: {result: result}
})
.then(function(result){
console.log(result);
})
};
};
vm.result in the Angular controller is for the result from the geoip2 Node module that performs the geolocation.
I can get the result in the console no problem but I'm not to sure how to pass it to Angular. I'm using the $http service but I'm not sure where to go from here...?
How do I pass the result from the geoip2 Node module to my Angular controller with $http?
The problem is that you are calling next before you are even done.
app.get('/', function (req, res, next) {
//next(); this line should be commented
// geolocation
geoip2.lookupSimple(ip, function(error, result) {
if (error)
return res.status(400).json({error: 'Something happened'});
return res.send(result);
});
});
Then on angular
$http({
method: 'GET',
url: '/yourURL'
}).then(function (response) {
console.log(response);
});
If you want to use the user IP to get location:
app.get('/', function (req, res, next) {
//next(); this line should be commented
// geolocation
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
geoip2.lookupSimple(ip, function(error, result) {
if (error)
return res.status(400).json({error: 'Something happened'});
return res.send(result);
});
});
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
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);
});
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.