OK first time user of Node, and I am trying to send data to backend/index.js
Requirements
Post data to back-end node
Retrieve posted data and store values as variables
Whats the problem
The post is 200 success, that works.
however when I navigate to :
http://localhost:8080/backend/index
I get :
Cannot GET /backend/index
Where am I going wrong ?
Here is my front end post post
var settings = {
"async": true,
"crossDomain": true,
"url": "http://localhost:8080/backend/index.js",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"id": "1223",
"token": "223",
"geo": "ee"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
I am trying to retrieve this data from and store as variable in the back end node.
backend/index.js
// grab the packages we need
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
// routes will go here
// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
// POST http://localhost:8080/api/users
// parameters sent with
app.post('/backend/index', function(req, res) {
var user_id = req.body.id;
var token = req.body.token;
var geo = req.body.geo;
res.send(user_id + ' ' + token + ' ' + geo);
});
UPDATE using screen shots
I think you didn't specify GET method, you can do like this
app.get('/', function(req, res) {
res.send('do something 1');
});
app.get('/backend/index', function(req, res) {
res.send('do something 2');
});
Hope this will help!
Because you Post Api and you can not get result without parameter.
Your Post Api will not give output until you hit only url on web browser, so need postman for Post Api.
Now you get Output without any problem.
Thanks in Advance
Related
I start learning Node.js and Express.js and I'm trying to create a simple API to list data from JSON file (using the GET method) and add a new user using the POST method.
the GET method works fine but the POST method does not work
when I request http://127.0.0.1:8080/listusers the API sends all users in a JSON file.
when I request http://127.0.0.1:8080/adduser the API has to add new User Info and send the new data back to the browser.
NOTE: I read all the questions on Stackoverflow about this problem but
non of them help me so I have to ask again.
the problem is when I request http://127.0.0.1:8080/adduser I get the following error
Cannot GET /adduser
here is the server.js:
var express = require('express');
var app = express();
var fs = require('fs');
var user = {
"user4" : {
"name" : "mounir",
"password" : "password4",
"profession" : "teacher",
"id": 4
}
};
app.post('/adduser', function (req, res) {
// First read existing users.
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data["user4"] = user["user4"];
console.log( data );
res.end(JSON.stringify(data) );
});
});
app.get('/listusers', function (req, res) {
fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
console.log(data);
res.end(data);
});
});
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log("listening at http://%s:%s", "0.0.0.0", port)
});
The answer is in the error. Cannot GET /adduser. Keyword GET! If you are making a post request, be sure you include the appropriate headers and that you are making a POST request, with a body, and not a GET request. For instance if you are using fetch:
const myInit = {
method: 'POST',
headers: myHeaders,
body: {
...
}
};
fetch("http://127.0.0.1:8080/adduser", myInit)
.then(res => {
...
});
My use case:
My case is that i'm making a bot for listening podcast in which user will make call to twilio number and bot will ask what type of podcast would you like to listen then record for 10 seconds
when recording finish, it say user to please wait while we are finding podcast
I want that recording in my webhook so i will figure out caller mood and find appropriate podcast mp3 file from my database and play to caller
Issue I'm Facing:
I'm getting empty body in all of my webhooks
My code:
var express = require("express");
var bodyParser = require("body-parser");
var VoiceResponse = require('twilio').twiml.VoiceResponse;
var app = express();
var port = (process.env.PORT || 4000);
app.use(bodyParser.json())
// helper to append a new "Say" verb with alice voice
function say(text, twimlRef) {
twimlRef.say({ voice: 'alice' }, text);
}
// respond with the current TwiML content
function respond(responseRef, twimlRef) {
responseRef.type('text/xml');
responseRef.send(twimlRef.toString());
}
app.post("/voice", function (request, response, next) {
console.log("request: ", request.body); //body is comming as empty object
var phone = request.body.From;
var input = request.body.RecordingUrl;
var twiml = new VoiceResponse();
console.log("phone, input: ", phone, input);
say('What type of podcast would you like to listen. Press any key to finish.', twiml);
twiml.record({
method: 'POST',
action: '/voice/transcribe',
transcribeCallback: '/voice/transcribe',
maxLength: 10
});
respond(response, twiml);
});
app.post("/voice/transcribe", function (request, response, next) {
console.log("request: ", request.body); //body is comming as empty object
var phone = request.body.From;
var input = request.body.RecordingUrl;
var twiml = new VoiceResponse();
var transcript = request.body.TranscriptionText;
console.log("transcribe text: ", transcript);
//here i will do some magic(Ai) to detect user mood and find an
//appropriate mp3 file from my database and send to twilio
var mp3Url = 'https://api.twilio.com/cowbell.mp3'
say('start playing.', twiml);
twiml.play(mp3Url);
respond(response, twiml);
});
app.listen(port, function () {
console.log('app is running on port', port);
});
API Test with postman:
added url as webhook on twilio:
Heroku Logs:
Twilio developer evangelist here.
You are using body-parser which is good. However, you are using the JSON parser. Twilio makes requests in the format of application/www-x-form-urlencoded so you should change:
app.use(bodyParser.json())
to
app.use(bodyParser.urlencoded({ extended: false }))
Then you should see the parsed body as part of the request.body object.
As an extra note, the transcribeCallback is sent asynchronously to the call. So returning TwiML in response to that request won't affect the call at all. You will need to modify the call in flight, by redirecting it to some new TwiML when you get the result of transcription. An example of updating a call with Node.js is below:
const accountSid = 'your_account_sid';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);
client.calls('CAe1644a7eed5088b159577c5802d8be38')
.update({
url: 'http://demo.twilio.com/docs/voice.xml',
method: 'POST',
})
.then((call) => console.log(call.to));
Title says it all. I'm new to this so I'm sure it must be a simple mistake.
Here's the controller
$scope.removeProduct = function(product){
console.log(product._id);
var inData = new Object();
inData._id = product._id;
console.log(inData);
$http({ url:"/api/deleteprod/", inData, method: "POST"
}).then(function () {
console.log("got here");
var index = $scope.vehicles.indexOf(product);
$scope.vehicles.splice(index, 1);
})
};
and here's the server side.
module.exports = function(app, mongoose, config) {
app.post('/api/deleteprod', function(req, res){
console.log("in app post",req);
var MongoClient = mongodb.MongoClient;
var url='mongodb://localhost:27017/seedsdev';
});
};
Obviously what I want is to pass the _id to the server so I can work with it, but when I output req it's about 50 pages long and has none of the info I wanted. Before it's passed the object can be seen to be fine fia console.log.
What's the rookie mistake I'm making?
When calling $http, you pass the post data with a data property. Currently you're passing an inData property. Change to this:
$http({ url:"/api/deleteprod/", data: inData, method: "POST" }).then(...)
Update:
On the server side, you'll need to make sure you have a JSON parsing middleware, like that from body-parser:
app.use(require('body-parser').json())
Once you are parsing the body using body-parser, you'll have a req.body property with the parsed JSON.
What you are missing are two below things.
1) Data in post request as suggested by #Jacob
2) A parser of Post param body-parser. //npm install body-parser --save
This will help you to parse the POST data in node js.
So code would look like
$scope.removeProduct = function(product){
console.log(product._id);
var inData = new Object();
inData._id = product._id;
console.log(inData);
$http({ url:"/api/deleteprod/", data: inData, method: "POST"
}).then(function () {
console.log("got here");
var index = $scope.vehicles.indexOf(product);
$scope.vehicles.splice(index, 1);
})
};
IN Backend
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
module.exports = function(app, mongoose, config) {
app.post('/api/deleteprod', function(req, res){
console.log("in app post",req.body._id);
var MongoClient = mongodb.MongoClient;
var url='mongodb://localhost:27017/seedsdev';
});
};
When I send a string value as the request, the req.body value is an object. I am using:
I have a factory cust1_service.postQuery:
.factory('cust1_service', function($http){
return {
postQuery : function(request){
console.log('cust1 req : ' + request);
console.log('typeof request : ' + typeof request);
var config = {'Content-Type' : 'text/plain'};
return $http.post('/cust1', request);
}
}
Here is how I call the factory in my controller:
cust1_service.postQuery(req_string).success(handleSuccess);
I am also using bodyParser.text() before my routes
var express = require('express'),
config = require('./config/config'),
bodyParser = require('body-parser'),
api = require('./app/routes/api.js');
var app = express();
app.use(bodyParser.text({
type: "text/*"
}));
app.use(express.static(__dirname + '/public')); //Serve static assets
require('./app/routes/api.js')(app, db);
app.listen(config.port, function() {
console.log('Listening on ' + config.port);
})
So....when I get to my routing api
app.route('/cust1')
.post(function(req,res){
console.log('this is req.body : ' + req.body);
req.body is [object Object]...am I sending the request as a text type incorrectly?? I need req.body to be a string.
Try to "stringify" the req.body to be sure if it's still passed as a JSON object. You can also try logging the console like console.log('this is req.body : ', req.body, ' --- ');
One solution you can try is to completely remove the use of the BodyParser middleware - this should force the body to be text.
SO you need to remove or comment out the line:
app.use(bodyParser.text({ type: "text/*"}))
You can look at a closely related question here.
I hope this helps;
I fairly new to MEAN, so sorry if this question is so obvious. I want to send an email to a contact when they click a send button. My code for handling a send email is using a post I am currently using a SendGrid Nodejs API to send the email. The problem is I keep running into a 400 Post Error.
This is the error I get in my Google Chrome Console
This is the error I get in my server terminal
This is in my controller.js:
$scope.send = function(contact) {
console.log("Controller: Sending message to:"+ contact.email);
$http.post('/email', contact.email).then(function (response) {
// return response;
refresh();
});
};
this code is in my server.js:
var express = require("express");
var app = express();
//require the mongojs mondule
var mongojs = require('mongojs');
//which db and collection we will be using
var db = mongojs('contactlist', ['contactlist']);
//sendgrid with my API Key
var sendgrid = require("sendgrid")("APIKEY");
var email = new sendgrid.Email();
var bodyParser = require('body-parser');
//location of your styles, html, etc
app.use(express.static(__dirname + "/public"));
app.use(bodyParser.json());
app.post('/email', function (req, res) {
var curEmail = req.body;
console.log("Hey I am going to send this person a message:" + curEmail);
var payload = {
to : 'test#gmail.com',
from : 'test1#gmail.com',
subject : 'Test Email',
text : 'This is my first email through SendGrid'
}
sendgrid.send(payload, function(err, json) {
if (err) {
console.error(err);
}
console.log(json);
});
});
Currently the email is hard coded but I will make the change after I fix the post issue. If you could point me in the right direction that would be very helpful. Thank you.
Looks like you're expecting the request body to contain JSON, with this line:
app.use(bodyParser.json());
Your error in your console says Unexpected token, which leads me to believe that body-parser encountered something it couldn't parse as JSON... probably a string. Which means that you sent your email as a string in the request body.
The easy fix would be to change how you're sending the request client-side:
var data = { email: 'some#email.com' }; // as opposed to just 'some#email.com'
$http.post('/email', data).then(refresh);
use this code
$scope.send = function(contact) {
console.log("Controller: Sending message to:"+ contact.email);
$http.post('/email', contact).then(function (response) {
// return response;
refresh();
});
};
and at server side
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser());