Not able to pass object with AngularJS to web backend - javascript

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';
});
};

Related

req.body.item undefined - DELETE request express js

I am a beginner to web development, and I am having trouble retrieving the parameters when sending a delete request to my local REST API (written using Express Js). I have already Googled the issue, but most are resolved by using body-parser.
When I return and print the req.body back to the console it comes out as:
{data: "{"Customer":"1"}"}
which seems to look correct?
But when I try and retreive
req.body.Customer;
in the routes.js file it comes out as undefined.
Am I missing something really obvious here?
JQuery function to make request
function DeleteItem(){
let data = {
Customer: $customerId.text()
}
data = JSON.stringify(data);
$.ajax({
url: "http://localhost:3000/Customers",
type: 'DELETE',
data: {
data
},
success: function(res) {
console.log(res);
BuildTable();
},
error: function(res) {
console.log(res);
alert(res);
}
});
}
Routes.js
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var appRouter = function(app) {
app.delete("/Customers", function(req, res) {
var customer = req.body.Customer;
console.log(customer);
res.send(req.body);
});
}
module.exports = appRouter;
First delete the line data = JSON.stringify(data);
then if you need the Customer you should write:
req.body.data.Customer;
or you can change your request like this:
function DeleteItem(){
let data = {
Customer: $customerId.text()
}
$.ajax({
url: "http://localhost:3000/Customers",
type: 'DELETE',
data: data,
success: function(res) {
console.log(res);
BuildTable();
},
error: function(res) {
console.log(res);
alert(res);
}
});
}
Right now you are creating a new object data and assigning the object you created before to it.

when i use ajax post json to web server(Nodejs), but the web server can't receive the data from client

the client code :
self.getjson = function () {
var timeinfo = new Object();
timeinfo.time = self.time;
timeinfo.address = self.address;
timeinfo.info = self.info;
return JSON.stringify(timeinfo);
};
alert(self.getjson());
$.ajax({
type: "POST",
//beforeSend:function(){$(".info").fadeIn('slow').html("正在提交,请稍后");},
url:'/user/add/timetemp',
data: self.getjson(),
beforeSend: function (xhr) {
xhr.setRequestHeader("Content-Type", "application/json");
},
success: function(data){
}
})
the server code app.js:
router.route('/user/add/timetemp')
.post(function(req,res){
console.log(req.body); // your JSON
res.send(req.body); // echo the result back
});
the answer from client:
enter image description here
there has data in the client.
the answer from server:
but the server is null
From the documentation:
req.body
Contains key-value pairs of data submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as body-parser and multer.
(My emphasis.) It continues with:
The following example shows how to use body-parsing middleware to populate req.body.
var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); // v1.0.5
var upload = multer(); // for parsing multipart/form-data
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.post('/profile', upload.array(), function (req, res, next) {
console.log(req.body);
res.json(req.body);
});
Side notes:
1. All of these variables on self are global variables. Global variables are a Bad Thing™. :-) Generally best to put your code in a scoping function and use locals within that scoping function.
2. new Object is almost never needed. Your getjson function can be much simpler:
self.getjson = function () {
return JSON.stringify({
time: self.time,
address: self.address,
info: self.info
});
};
or (slightly more convenient when debugging):
self.getjson = function () {
var timeinfo = {
time: self.time,
address: self.address,
info: self.info
};
return JSON.stringify(timeinfo);
};
3. There's no need for your beforeSend callback on ajax; just use the built-in contentType option:
$.ajax({
type: "POST",
//beforeSend:function(){$(".info").fadeIn('slow').html("正在提交,请稍后");},
url: '/user/add/timetemp',
data: self.getjson(),
contentType: 'application/json',
success: function(data) {
}
});

Why does my $http.post return a 400 error?

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());

how to read my json and send it to an email in pure nodejs

I would like NodeJS server, post.js file, to send the json object from the AJAX request to an email using only pure NodeJS.
The following is the front-end code that sends the AJAX request:
$(document).ready(function() {
$("#contact").submit(function () {
var data = {};
$.each($(this).serializeArray(), function (key, value) {
data[value.name] = value.value;
});
data.interest = [data.interest1, data.interest2, data.interest3];
delete data.interest1;
delete data.interest2;
delete data.interest3;
console.log(data);
$.ajax({
type: "POST",
data: JSON.stringify(data),
dataType: 'json',
url: "post.js",
success: function (data) {
$("#contact").addClass('success');
},
error: function () {
$("#contact").addClass('error');
}
});
return false;
});
});
Nodemailer offers a great way to have your node.js server send emails with easy setup. With this you can set up a simple node server such as:
//untested node.js code only for reference.
var express = require('express')
var app = express();
var nodemailer = require('nodemailer');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var transporter = nodemailer.createTransport('TODO: setup your SMTP');
app.post('/', function (req, res) {
var mailOptions = {
from: "TODO: sender",
to: "TODO: recipient",
text: req.body
}
app.listen('TODO: some port');
Check nodemailer's documentation for details on setting up the server to suit your needs.

HTTP request from within Express/Node.js

I'm trying to set up an express service for a program that I'm writing that contacts an external API and then returns the results so it can be stored in a Mongo I have set up.
This seems like it should be fairly straightforward, but I'm new to Node.js/Express and I'm getting a "Can't set headers after they are sent" error.
I'm getting the data that I want from the external API, but how to send that data properly back to my Angular app.js so it can update in my table?
"addSelected()" is the function I'm calling in my app.js to kick off the process. The "data" prints part of the way through the full response but then cuts off and gives me the "Can't set Headers after they are sent" error. From what I understand this is from sending the response and then trying to modify the response header after the fact.. but I'm unsure of a workaround or if I'm just formatting everything wrong as this is my first swing at MEAN stack in general.
I know the problem is on the line "res.send(data)" in server.js but I don't know how to correctly format the response.
My code:
server.js
//server.js
//setup ==============================
var express = require ('express');
var request = require('request');
var app = express();
var mongoose = require('mongoose');
var https = require('https');
//config ============================
app.use(express.static(__dirname + '/public/'));
console.log("running PipeHelper");
mongoose.connect('mongoedit');
var Schema = mongoose.Schema;
var opSchema = new Schema({
title: String,
description: String,
company: String,
post_date: String,
close_date: String,
contact: String,
location: String,
url: String,
notice_type: String
});
var item = mongoose.model('item', opSchema);
//routes===========================
//returns full database
app.get('/api/db', function(req, res){
item.find({},function(err, items){
if (err) res.send(err);
res.json(items);
});
});
//searches FBO for opportunities to add to database
app.get('/api/search:FBO_key', function(req, res){
var data;
console.log("2");
var baseURL = "api.data.gov"
var params = "/gsa/fbopen/v0/opps?q=" + req.params.FBO_key;
params += "&api_key="+"keyyyy";
params += "&all";
params += "&start=0";
params += "&p=1";
params += "&limit=10";
url = baseURL+params;
var options = {
port: 443,
host: 'api.data.gov',
path: params,
method: 'GET'
};
//get FBO data
var request = https.request(options, function(response){
console.log("4");
response.on('data', function (chunk){
//response data to send back to app.js
data += chunk.toString();
res.send(data);
});
});
console.log("3");
request.end();
request.on('error', function(e){
console.error(e);
});
});
app.get('/', function(req,res){
res.sendfile('./public/index.html');
});
app.listen(8000);
app.js
var app = angular.module("pipeHelper", ['smart-table']);
app.controller('mainCtrl', [
'$scope', '$http', function($scope, $http){
$scope.selected = [];
$scope.displayData= [];
$scope.items=[];
$scope.FBOsearch;
//populates table on startup with whole DB
$http.get('./api/db')
.success(function(data){
$scope.items=data;
$scope.displayData = [].concat($scope.items);
})
.error(function(data){
console.log('Error: '+data);
});
$scope.addSelected = function(){
//search FBO, add opportunities, update table
console.log("1");
$http.get('./api/search'+'NGA')
.success(function(data){
console.log("5");
console.log(data);
$scope.items=data;
$scope.displayData= [].concat($scope.items);
})
.error(function(data){
console.log('Error: ' +data);
});
};
$scope.isSelected = function(item){
//if its selected, remove it
// if its unselected, add it
if ($scope.selected.indexOf(item)==-1){
$scope.selected.push(item);
}
else{
$scope.selected.splice($scope.selected.indexOf(item), 1);
}
console.log($scope.selected);
//temp placeholder function. Eventually add to array of selected objects for placement in Pipeliner/deletion
};
}]);
solved the issue. I was unaware that response.on('data') gets called multiple times, thus calling my res.send(data) multiple times and incompletely causing it to crash with the error. I added the following to the request function:
response.on('end'function(){
res.send(data);
};
basically when the external API data is finished coming in, send it with express. Learn by doing I suppose. Hope this helps someone eventually.
I can't leave a comment, so I will just make it an answer.
I would recommend installing node-inspector, npm install -g node-debug. Then run your app with node-debug server.js. This will spawn a new instance of Firefox or Chrome dev tools and allows you to debug your nodeJS code. Very useful.
The error you are seeing is most likely related to request.end(), if I were to guess. After .end() is called, you can no longer modify the header content. I doubt it would make a difference, but try putting the request.end() after you have the request.on('error') call.
EDIT: 10/15/15
I would highly recommend installing VS Code. It has a built-in debugger for node apps.

Categories

Resources