Can't get data from $http.post - javascript

So basically, I have a form and I cannot fetch data typed into it.(I'm using angular and node.js)
req.body
req.params are both empty
My html form :
<form ng-submit="sendTradelink()">
<md-input-container class="md-accent">
<label>Enter your tradelink</label>
<input ng-model="tradelink">
</md-input-container>
<md-button type="submit" class="md-raised md-accent">Send</md-button>
</form>
Controller :
$scope.sendTradelink = function () {
Auth.send()
.success(function (res) {
$location.path('/');
});
}
Service :
authFactory.send = function (tradelink) {
return $http.post($api.url + 'tradelink', {tradelink: tradelink});
};
Server side file where I want to work with data inserted into form:
api.post('/tradelink', function(req, res){
console.log(req.user.id);
console.log(req.params);
console.log(req.body);
res.json({
success: true,
message: 'tradelink received'
})
});
logs for controlling, empty every time.

As mentioned in comments, Express does not parse the body. POST requests are much more complex that GET ones, so the parser lies in a separate package, body-parser:
npm install --save body-parser
// server.js
api.use(bodyParser.urlencoded({
extended: true
}));
api.post('/tradelink', function(req, res) {
console.log(req.body.tradelink);
});

#Amadan answer is right. You also need to update the controller:
Auth.send($scope.tradelink)

Related

Req.Body undefined NODE.JS POST Request

I'm currently working on a simple Node.JS app that communicates with mysql database.
The app gets data from the database and puts it in a table using app.get and it works fine.
The problem I am having is that req.body is not returning anything when using app.post. The app will submit to the database, but because req.body is not returning anything, the values are null. It will post actual values if I swap the req.body variables with hardcoded variables e.g. "12320".
I have therefore isolated the problem to post requests which use req.body.
If I console log req.body it is empty.
I have read just about every stackoverflow question on this and have not been able to find a solution.
I have tried reinstalling body-parser, express, morgan, and mysql.
I have tried recreating the app in a fresh directory and installing the modules again.
I have tried renaming the variables incase that was having some effect (e.g. name="test", req.body.test)
But all of this was to no avail.
<form id="submit_missing" action="/submit_quote" method="POST" enctype="multipart/form-data">
<input type="text" id="submit_quote_id" name="submit_quote_id" placeholder="Quote ID">
<input type="text" id="submit_priority" name="submit_priority" placeholder="Priority" list="priority_list">
<input type="text" id="submit_customer" name="submit_customer" placeholder="Customer">
<input type="text" name="submit_who" id="submit_who" placeholder="Who's On it" list="purchasing">
<input type="text" id="submit_account_manager" name="submit_account_manager" placeholder="Account Manager" list="account_managers">
<button id="submit_quote">SUBMIT</button>
<form>
// server.js
const express = require('express')
const app = express()
const morgan = require('morgan')
const mysql = require('mysql')
const bodyParser = require('body-parser')
app.use(bodyParser.json({ type: '*' }))
app.use(bodyParser.urlencoded({ extended: true }))
app.use(express.static('./public'))
app.use(express.static('./files'))
const user = ***
const pass = ***
function getBoardConnection() {
return mysql.createConnection({
host: "localhost",
port: "3306",
user: user,
password: pass,
database: "board"
})
}
app.get('/get_board_quotes', (req, res) => {
const con = getBoardConnection()
const queryString = "SELECT * FROM board_quotes WHERE quote_complete = '0'"
con.query(queryString,(err, rows, fields) => {
if (err) {
console.log("Failed to query for /get_board_quotes : " + err)
}
console.log("Getting data from database for /get_board_quotes")
res.json(rows)
})
})
app.post('/submit_quote/', (req, res) => {
console.log(req.body)
quote_id = req.body.submit_quote_id
priority = req.body.submit_priority
customer = req.body.submit_customer
who_quoted = req.body.submit_who
account_manager = req.body.submit_account_manager
type = ""
queryString = "INSERT INTO board_quotes (quote_id, priority, customer, who_quoted, account_manager, quote_type) \
VALUES (?, ?, ?, ?, ?, ?)"
getBoardConnection().query(queryString, [quote_id, priority, customer, who_quoted, account_manager, type], (err, results, field) => {
if (err) {
console.log("Failed to insert new board order " + err)
return res.redirect('/board/quotes.html')
}
console.log("Inserted a new board with id ")
res.redirect('/board/quotes.html')
})
})
app.listen(6565, () => {
console.log("Server is running")
})
Output
Server is running
Getting data from database for /get_board_quotes
{}
Failed to insert new board order Error: ER_BAD_NULL_ERROR: Column 'quote_id' cannot be null
{} is the output for console.log(req.body)
Any help would be greatly appreciated.
The issue you’re having is that you’ve set enctype="multipart/form-data" on your <form> HTML tag. By default, body-parser doesn’t parse bodies with a Content-Type header of multipart/form-data, which is what you’re telling the browser to send.
There is an easy way to fix this: I’d recommend just not setting enctype on the <form> element, as the browser will default to application/x-www-form-urlencoded and this is the type of form body body-parser will parse by default.
You can otherwise try passing type: "multipart/form-data" as an option when you call bodyParser.urlencoded(), which will make body-parser parse anything sent to it with that content type. (Correction: body-parser actually just silently fails for me if I tell it to parse multipart/form-data)
This question/answer may be of further help.
Body parser does not work with : Content-Type:multipart/form-data header
Multer is used to handle Content-Type:multipart/form-data header , while uploaing file with form-data
Body Parser only work with :
Content-Type:application/x-www-form-urlencoded ,
Content-Type:application/json
remove enctype="multipart/form-data" in your form & try to submit form
At first I would recommend to use curl utility to simplify POST request, issue the following (I'm assuming here that you calling from the same machine hence 'localhost'):
curl -d "submit_quote_id=999" -X POST http://localhost:6565/
and see what you get

req.body returns undefined while using body-parser

I'm trying to build an API that receives a POST req to create a user but I am getting undefined errors for all of my req.body requests. My app is set up like this (simplified for brevity):
User controller that gets called by Express Router in my user routes file
/controllers/user.js
userController.addUser = function(req, res) {
let user = new User();
user.username = req.body.username;
user.first_name = req.body.first_name;
user.last_name = req.body.last_name;
user.email = req.body.email;
user.type = req.body.user_type
// This returns undefined as does all other req.body keys
console.log("REQ.BODY.EMAIL IS: " + req.body.email);
}
User Route File:
/routes/user.js - requires user controller above
router.post('/user/create', userController.addUser);
Main App:
all routes and controllers work per my tests except where req.body.* is used
index.js - main app file
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', routes);
I have looked through the Express documentation and through countless StackOverflow posts with no luck. Let me know if you need further clarification.
My issue was how I was sending the body to the API endpoint. I was using form-data instead of x-www-form-urlencoded with Postman. User error
Sometime with change in version body-parser seems to not work, in that case just use following, this will remove dependency from body-parser:
router.post('/user/create', (req, res, next) => {
let body = [];
req.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
// Data is present in chunks without body-parser
body.push(chunk);
}).on('end', () => {
// Finally concat complete body and will get your input
body = Buffer.concat(body).toString();
console.log(body);
// Set body in req so next function can use
// body-parser is also doing something similar
req.body = body;
next();
});
}, userController.addUser);

HTML/server function interaction (GET, POST)

I think I'm lacking some understanding of these fundamental concepts (I've read a decent amount of resources and examples) of how these functions work server-side and how the html interacts with them. I was writing methods earlier today and communicating between the server and html perfectly, manipulating an array I had stored locally on the server file. For reference I'll show you how I was doing it.
jQuery script in html file:
$.post("/deck", { name: "Angel of Fury", power: 666 }, function(){
});
server file:
var express = require('express'),
app = express(),
db = require('./db'),
bodyParser = require('body-parser'),
controller = require('./controller');
//add body parser middleware
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
//Serves static pages
app.use(express.static(__dirname + ('/')));
//loads the html page
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
var server = app.listen(3000, function () {
var host = server.address().address;
host = (host === '::' ? 'localhost' : host);
var port = server.address().port;
console.log('listening at http://%s:%s', host, port);
});
var deck = [ ];
app.get('/deck', function(req, res) {
res.send(deck);
});
app.post('/deck', function(req, res) {
console.log(req.body);
var card = req.body;
deck.push(card);
res.send(deck);
});
Given this code I could navigate to "localhost:3000/deck and any changes I made were stored in the array and displayed at this address. Simple enough. I've taken that a step farther and implemented a database, mySQL and have successfully written methods for insertion, select, delete, etc..
<script>
$("submit").on("click", function(){
$.post("/users", { name: username.value, password: psw.value, email: email.value}, function(){
console.log("post successful..");
});
});
</script>
<body>
<form>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="password" name="psw"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit">
</form>
</body>
I added the above form jquery script to the html page. And attempted to add the server functions below.
app.get('/users', function (req, res) {
});
app.post('/users', function (req, res) {
console.log(req.body);
});
I thought that this would allow me to use the req.body object on submission of the form. Please correct me if I'm going about this the wrong way, I would be grateful for any help/tips.
You can do two things:
Use event.preventDefault() to stop the form submission.
Change the button type to button instead.
As you have not prevented the form to submit so, whenever you click the submit button it submits the form and it makes a default get request if method attribute to post is not been provided.
$("submit").on("click", function(ev){
ev.preventDefault(); // <-------- HERE
$.post("/users", { name: username.value, password: psw.value, email: email.value}, function(){
console.log("post successful..");
});
});
Or make a small change at your markup:
<input type="button"....../>
In the form.
As per your latest comment, add a class/id attribute to the button and change the selector:
<input type="submit" id="submit"...../>
Now in js you have to use this:
$("#submit") // <---- notice the # which denotes the ID selector in jQuery.

How to write result in a file by using node.js and express?

I've built an application using node.js and express.js on top of elasticsearch. This is very simple application with a search box. When you search for a query, it prints result in JSON format. For eg, if I search for keyword "white", the output looks like this: http://i.stack.imgur.com/VHuWl.png
Now I want to store this result in a file(for eg output.json).This is my json file:
var fs = require('fs');
var path = "output.json";
var express = require('express'); //To make use of Express' routing capabilities you need to initiate a new Express Router.
var router = express.Router(); //To make use of Express' routing capabilities you need to initiate a new Express Router. get, put, post, delete, all
var searchModule = require('../search_module/search.js');
//There are two ways of using the router methods. You can define one route (for example /home) and attach the methods to it, or you can create a new method for each route.
/* GET home page. */
router.get('/', function(req, res) { //.get() - when you visit a website you make a GET request. You can get data from a URL in a GET request too.
res.render('index', { title: 'Express' });
});
router.post('/search-results', function(req, res) {//.post() is a method used everywhere for posting data to a server / app. You'll want to use this for submitting forms.
searchModule.search(req.body, function(data) {
res.render('index', { title: 'Express', results: data });
});
});
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
module.exports = router;
When I tried using writeFile method of node.js, I am getting an Reference error showing that "data" is not defined. My error looks like this: http://i.stack.imgur.com/lwXfW.png
I am not able to figure out this error. Is there any other way to write the output to a file by using node.js and express?
Edit: I edited my javascript
var fs = require('fs');
var path = "output.json";
var express = require('express'); //To make use of Express' routing capabilities you need to initiate a new Express Router.
var router = express.Router(); //To make use of Express' routing capabilities you need to initiate a new Express Router. get, put, post, delete, all
var searchModule = require('../search_module/search.js');
//There are two ways of using the router methods. You can define one route (for example /home) and attach the methods to it, or you can create a new method for each route.
/* GET home page. */
router.get('/', function(req, res) { //.get() - when you visit a website you make a GET request. You can get data from a URL in a GET request too.
res.render('index', { title: 'Express' });
});
router.post('/search-results', function(req, res) {//.post() is a method used everywhere for posting data to a server / app. You'll want to use this for submitting forms.
searchModule.search(req.body, function(data) {
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
res.render('index', { title: 'Express', results: data });
});
});
module.exports = router;
But when I ran this javascript, I got this output:
http://i.stack.imgur.com/rfBq0.png
I am not getting the JSON output. My output should look like this: http://i.stack.imgur.com/VHuWl.png
I am also using an ejs file with my javascript for the frontend(index.ejs) which looks like this:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<form action='/search-results' method='post'>
<input type="text" name="searchTerm" placeholder="your search term here">
<button type="submit"> SEARCH </button>
</form>
<ul>
<% if(locals.results) { %>
<pre>
<%= JSON.stringify(results,null,2) %>
</pre>
<% results.forEach( function( result ) }) %>
<% } %>
</ul>
</body>
</html>
Do I need to get output from this file?
The data variable is not defined at this point.
You can move your fs.writeFile function in the searchModule.search call like this:
searchModule.search(req.body, function(data) {
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
res.render('index', { title: 'Express', results: data });
});
or declare your variable before and set it in the searchModule.search call, to be disponible after in the scope to write your file:
var fileData;
searchModule.search(req.body, function(data) {
fileData = data;
res.render('index', { title: 'Express', results: data });
});
fs.writeFile(path,fileData,function(err){
if(err) console.error(err);
})
I'm looking at this block:
fs.writeFile(path,data,function(err){
if(err) console.error(err);
})
You've declared path at the top of your code, but data appears to be undefined in this context.

AngularJS $http.get not retrieving the backend data

i am new to the "Angularjs and Nodejs" combination and i am trying to make a simple crud app. The problem is, when i use $http.get in angular, it doesnt go to the backend.
Here are my codes:
server.js (nodejs)
var connection = util.getDBConnection();
app.use(express.static(__dirname + "/public"));
app.use(bodyParser.json());
//routes = require('./routes/routes')(app, connection);
app.get('/', function(req, res) {
console.log("Backend");
connection.query("SELECT * FROM user_info;", function(err, rows){
if(err){
res.redirect('/error');
console.log("Error in the database: " + err);
}
res.end(JSON.stringify(rows));
console.log("Connected to the Database!");
});
});
angularmodule.js
var app = angular.module('two_way', ['ngRoute']);
app.controller('two_way_control', function($scope, $http){
$scope.message = "Hello from controller";
$http.get('/').success(function(data){
console.log("http get");
console.log(data);
$scope.profile_pictures = data;
});
});
and console.log(data) returns the whole index.html
index.html
<body>
<div id="container" ng-app="two_way" ng-controller="two_way_control">
<div class="row" ng-repeat="data in profile_pictures">
{{message}}
<div class=".col-sm-6 .col-md-5 .col-lg-6">
<h4>User Say's</h4><hr>
<p>
This is a Demo feed. It is developed to demonstrate Two way data binding.
</p>
{{ data.profile_picture }}
<img src="{{data.profile_picture}}">
</div>
</div>
</div>
</body>
But this code returns the mysql data in json format:
app.get('/load', function(req, res) {
console.log("Backend");
connection.query("SELECT * FROM user_info;", function(err, rows){
if(err){
res.redirect('/error');
console.log("Error in the database: " + err);
}
res.end(JSON.stringify(rows));
console.log("Connected to the Database!");
});
});
Please help. Thanks in advance and sorry for the bad english.
For fix the error in the chrome console
"GET http://localhost:8000/%7B%7Bdatas.profile_picture%7D%7D 404 (Not Found)"
i suggest you to use the ngSrc directive, so instead of
<img src="{{datas.profile_picture}}">
use
<img ngSrc="{{datas.profile_picture}}">
As described in the doc
Hope this help
In Express, you need to respond with a request. Use something such as res.send and send data down.
http://expressjs.com/api.html#res.send
Sends the HTTP response.
The body parameter can be a Buffer object, a String, an object, or an
Array. For example:
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });
This method performs many useful tasks for simple non-streaming responses:
For example, it automatically assigns the Content-Length HTTP response header field (unless previously defined) and provides automatic HEAD and HTTP cache freshness support.
When the parameter is a Buffer object, the method sets the Content-Type response header field to “application/octet-stream”, unless previously defined as shown below:
res.set('Content-Type', 'text/html');
res.send(new Buffer('<p>some html</p>'));
When the parameter is a String, the method sets the Content-Type to “text/html”:
res.send('<p>some html</p>');
When the parameter is an Array or Object, Express responds with the JSON representation:
res.send({ user: 'tobi' });
res.send([1,2,3]);
http://expressjs.com/api.html#res.end
Ends the response process. Inherited from Node’s http.ServerResponse.
Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().
res.end();
res.status(404).end();
I got the answer, i just need to initiate the http function
var app = angular.module('two_way', []);
app.controller('two_way_control', function($scope, $http){
$scope.message = "Hello from controller";
$scope.load = function(){
$http.get('/LoadAll').success(function(data){
console.log("http get");
$scope.profile_pictures = data;
});
};
$scope.load();
});
but i still get an error in the chrome console
"GET http://localhost:8000/%7B%7Bdatas.profile_picture%7D%7D 404 (Not Found)"
in <img src="{{datas.profile_picture}}">
Change
<img src="{{datas.profile_picture}}">
to
<img src="{{data.profile_picture}}">

Categories