Not seeing post data in node server - ajax

While making below ajax call, I am not seeing any post data in node server side.
$.ajax({
type: "POST",
url: window.location.origin + "/api/books",
data: {
title: "Javascript some good partd",
author: "Douglas crockford",
releaseDate: new Date(2013, 4, 2).getTime()
},
dataType: "json",
success: function(data) {
console.log(data);
}
});
After doing some search, I found out it could be because of body-parser configuration but unable to get it right. Please find below the node server configuration.
app.configure( function() {
app.use(bodyParser());
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(application_root, 'site')));
app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});
And API call is:
app.post('/api/books', function (req, res) {
console.log(req.body);
var book = new BookModel({
title: req.body.title,
author: req.body.author,
releaseDate: req.body.releaseDate
});
return book.save(function (err, response) {
if (!err) {
return res.send(book);
} else {
console.log(err);
}
});
});
req.body is logged as undefined. Can anyone please help on debugging the issue?

Drop the app.configure function.
All the code inside of it can be left floating in that file.
My best guess would be that its not firing off that function.
I tend to use this code
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

Related

File upload using jquery/ajax for REST API

I was trying to upload file to a remote server using REST api by ajax/jquery with the following script, but it returns 400 error with a Bad request. I have tested the end point with curl, which is giving correct response and file is being uploaded.
$(document).ready(function () {
$("#btnSubmit").click(function (event) {
//stop submit the form, we will post it manually.
event.preventDefault();
fire_ajax_submit();
});
});
function fire_ajax_submit() {
// Get form
var form = $('#fileUploadForm')[0];
alert(form.files[0]);
var data = new FormData(form);
data.append("CustomField", "This is some extra data, testing");
$("#btnSubmit").prop("disabled", true);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "http://10.13.20.166:5332/fileUploadtoFolder",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
$("#result").text(data);
console.log("SUCCESS : ", data);
$("#btnSubmit").prop("disabled", false);
},
error: function (e) {
$("#result").text(e.responseText);
console.log("ERROR : ", e);
$("#btnSubmit").prop("disabled", false);
}
});
}
Change your code 👇
var data = new FormData(form);
Use this code 👇
// Create an FormData object
var data = new FormData(document.getElementById("fileUploadForm"));
Try again

Backbone - rest POST service is called more than once

I have a problem when I call a REST service by POST to updates tables in MySQL.
I'm working with BackboneJS and when click Save button, call the service and passed POST parameters
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson, //data send to REST service by POST
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
},
error: function(data){
console.log(data.msg);
}
});
But the problem occurs when income and leave the editing screen. Assuming I made a change and it worked perfectly bringing me back a single "OK", when I go back into the editing screen and record again, I get twice the word "OK".
If I repeat this step to enter and exit the screen edition, duplicate responses are based on the number of times into the screen edition.
I don't know if it's a problem about I'm doing wrong with BackboneJS...?? I'm doing this:
editAdverts: function(){
var editAdvertsView = new EditAdvertsView ();
$('#container-page').append(editAdvertsView.render(idAdverts).el);
}
It can also be a topic of AJAX?
I hope someone can help me with this issue because I am not an expert in BackboneJS
Thanks a lot!
Diego
It's hard to tell without more code but I'm pretty sure it's because you are creating a model each time you are using editAdvert.
Instead of creating a model each time just create one at the init of your view then call the fetch/save function anytime you need an update. Creating the model once is enough.
edit: zombies views is a good thing to check too as brent noticed in comment, we can't tell without more code.
This is de code about route:
var Index = {
start: function() {
var list_view = new MainView();
}
};
var AppRouter = Backbone.Router.extend ({
routes: {
'goAdvert' : 'goAdvert'
},
goAdvert: function(){
var viewAdvertsView = new ViewAdvertsView();
$('#container-page').append(viewAdvertsView.render().el);
}
});
var MainView= Backbone.View.extend({
el: $('#contenedor-body'),
initialize: function() {
this.render();
},
render: function() {
// here is the code about main page. It's not important!
},
});
new AppRouter;
Index.start();
Backbone.history.start();
This is the viewAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'dtBootstrap',
'../../view/editAdvertsView',
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables, DtBootstrap, EditAdvertsView){
var viewAdverts = Backbone.View.extend({
events: {
'click #edit' : 'editAdvert'
}
editAdvert: function(){
$('#container-page').empty();
var idAdvert = $(event.target).data('id');
editAdvertView = new EditAdvertsView();
$('#container-page').append(editAdvertView.render(idAdvert).el);
},
render: function() {
// load viewAdverts
}
});
return viewAdverts;
}
);
And this is editAdvertsView.js
define([
'jquery',
'underscore',
'backbone',
'jqueryuniform',
'bootstrap',
'handlebars',
'jqueryDataTables',
'functions',
'sessionManage',
'slimscroll',
'jqueryCustomSlimscroll',
'slimscrollMin',
'jqueryblockui',
'text!../../html/editAdverts.html',
'maps',
'fancybox'
], function($, _, Backbone, jqueryuniform, Bootstrap, Handlebars, JQueryDataTables,
Functions, SessionManage, Slimscroll, JqueryCustomSlimscroll, SlimscrollMin,
Jqueryblockui, EditAdverts, Maps, Fancybox){
var Advert= Backbone.View.extend({
el: $('#container-page'),
events: {
'click #saveChanges' : 'doSaveChanges'
},
doSaveChanges: function(){
var data = null;
var rootURL = "http://localhost/php/slim/slim/advert/update" + "?date=" + $.now();
dataJson = {
id: $("#id").val(),
product: $("#product").val(),
price: $("#price").val(),
client: $("#client").val(),
country: $("#country").val(),
tel: $("#telephone").val(),
cel: $("#cellphone").val()
};
$.ajax({
type: 'POST',
url: rootURL,
data: dataJson,
cacheControl: "no-cache",
dataType: "json",
success: function(data){
console.log("OK");
error: function(data){
console.log(data.msg);
}
}
},
render: function(codInmueble) {
var self = this;
var editTemplate = Handlebars.compile(EditAdverts);
self.$el.html(editTemplate());
return this;
}
});
return Advert;
}
);

Post jQuery JSON Object to NodeJs Restify

I want to know why it is so hard to post a simple JSON string in a /:parameter to restify. I have followed many examples but have not found anything concrete.
I have the following code in the front end.
$("#btnDoTest").click(function() {
var jData = {
hello: "world"
};
var request = $.ajax({
url: "http://localhost:8081/j/",
async: false,
type: "POST",
data: JSON.stringify(jData),
contentType: "application/javascript",
dataType: "json"
});
request.success(function(result) {
console.log(result);
});
request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
I am succesful in sending simple text if I concatenate the param after the j/. But what I want to send is an object like this {hello:"world"} and reconstruct it back in nodeJS and work with it.
--Edit:
This is my nodejs file
/* the below function is from restifylib/response.js */
var restify = require("restify");
/* create the restify server */
var server = restify.createServer({
});
server.use(restify.bodyParser({ mapParams: true }));
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
return next();
}
);
server.post('/j/', function (req, res, next) {
//res.send(201,"REceived body: "+JSON.stringify(req.params));
res.send(201,"REceived body: "+JSON.stringify(req.params));
return next();
});
var port = 8081;
server.listen(port);
console.log("Server listening on port " +port)
Any help would be appreciated thanks.
0x
I finally got it working.
--Front end code
$("#btnDoTest").click(function() {
var request = $.ajax({
url: "http://localhost:3000/j",
async: false,
type: "POST",
data: {
blob: {wob:"1",job:"2", ar:[1,2,{a:'b'}]}
},
contentType: "application/x-www-form-urlencoded", //This is what made the difference.
dataType: "json",
});
request.success(function(result) {
console.log(result);
});
request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
});
NodeJs services
/* the below function is from restifylib/response.js */
var restify = require("restify");
/* create the restify server */
var server = restify.createServer({
});
server.use(restify.bodyParser());
server.use(restify.CORS());
server.post('/j/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
// req.params == data on jquery ajax request.
res.send(200, JSON.stringify(req.params));
console.log(req.params.blob.ar[2].a)
res.end();
return next();
});
var port = 3000;
server.listen(port);
console.log("Server listening on port " + port)
Don't stringify it. Try this, note the two changes, I removed the JSON.stringify and switched to application/json, as its JSON and not JavaScript.
var request = $.ajax({
url: "http://localhost:8081/j/",
async: false,
type: "POST",
data: jData,
contentType: "application/json",
dataType: "json"
});
application/javascript should only be used when doing JSONP.
my answer first!
jquery:
$.ajax({
url: url,
method: 'post',
data: JSON.stringify({key:value}),
contentType: "application/json"
});
node http:
server.post('/1', function(req, res) {
var body = req.body;
var dataValue = body.dataKey;
});
why?
data of $.ajax is just for what to send to server end, its datatype has not be defined, so when use JSON.stringify({key:value}), the data will be sent as a string like '{key:"xxx"}', and node recieve a string, not a json object even the string structure looks like a json. but after we add contentType: "application/json" in $.ajax, when node recieve the data, it will be a real json object type data.

ASP.Net MVC Checking Facebook Login status before executing code in the controller

I'm using Facebook JavaScript SDK to log in with Facebook,
the only problem is that the JavaScript code executed after the controller.
all i want is to check if the user logged in before going to the controller.
Any help?
This is the java script Code
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({ appId: '#Facebook.FacebookApplication.Current.AppId', channelURL: '#Request.Url.Scheme://#Request.Url.Authority#Url.Content("~/fbchannel.ashx")', cookie: true, xfbml: true, oauth: true });
FB.Event.subscribe('auth.login', function (response) { window.location.reload(); });
FB.Event.subscribe('auth.logout', function (response) { window.location.reload(); });
FB.Event.subscribe('auth.authResponseChange', function (response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
$.ajax({
url: '/Home/SaveAccess',
type: 'POST',
data: { A: accessToken },
success: function (data) {
},
error: function() {}
});
var field = document.createElement("input");
field.setAttribute("type", "hidden");
field.setAttribute("name", 'accessToken');
field.setAttribute("value", accessToken);
form.appendChild(field);
document.body.appendChild(form);
form.submit();
} else if (response.status === 'not_authorized') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
$.ajax({
url: '/Home/SaveAccess',
type: 'POST',
data: { A: accessToken },
success: function () {
}
});
} else {
}
});
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
i save the Access Token in a session, the problem is that this code executed after the controller code.
Didn't understand exactly what you wanted. Here's a solution for what I did.
You can call FB.getLoginStatus anytime to check if the user is connected or not.
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
// user logged in and connected
}
});
You can also add this in the fbAsyncInit to check user status every time the page loads.

How to use ajaxmanager with jquery ajax request?

I'm trying to use the ajax blockmanager plugin to manage my jquery ajax requests, but I'm not sure how to implement it...
// Follow button click event
$('#loginBtn').click(function () {
var that = this;
var request = {
'username': $('#txtUsername').val(),
'password': $('#txtPassword').val()
};
var params = $.toJSON(request);
ajaxManager.add($.ajax({
type: "POST",
url: "ajax/Login.aspx/Login",
data: params,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
if (result.d === true) {
window.location = "dashboard.aspx";
}
else {
$('#errorMessage').slideDown();
}
}
}));
I know it's a bit outdated question... But if anyone comes across this issue:
You are passing the already created/started request as a parameter to the manager.
You should only pass its options. The request will be created and handled by the manager.
ajaxManager.add({
type: "POST",
url: "ajax/Login.aspx/Login",
data: params,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
if (result.d === true) {
window.location = "dashboard.aspx";
}
else {
$('#errorMessage').slideDown();
}
}
});
Do you have ajaxManager instantiated?
//create an ajaxmanager named cacheQueue
var ajaxManager = $.manageAjax.create('cacheQueue', {
queue: true,
cacheResponse: true
});
You first create the manager
this.ajaxManager = $.manageAjax.create("aiapi", {
queue: true,
cacheResponse: true,
maxRequests: 3,
abort: this.abortCallback
});
where the queue of calls is active, max concurrent requests are 3, and the caching is enabled. The common abortCallback is like
this.abortCallback = function (response) {
Logger.log("APIManager.abortCallback " + Utils.toString(response));
};
It's convenient to add the common ajaxSetup setup like
$.ajaxSetup({
cache: true,
timeout: 10 * 1000
});
Here you can see the response timeout in msec set to 10 sec.
You then do a GET like
this.DoGet = function (url, method, timeout) {
return new Promise((resolve, reject) => {
var options = {
type: 'GET',
url: url + method,
contentType: "application/json",
timeout: (15 * 1000) // sets timeout to 60 seconds
};
if (timeout) options.timeout = timeout;
const errorCallback = function (error) {
console.error(error);
return reject(error);
};
const successCallback = function (data) {
return resolve(data);
};
const completeCallback = function (data) {
return resolve(data);
};
options.error = errorCallback;
options.success = successCallback;
//options.complete= completeCallback;
$.manageAjax.add("default-queue", options);
/*$.ajax(options)
.done(function (data) {
return resolve(data);
})
.fail(function (error) {
console.error(error);
return reject(error);
})
.always(function () {
// called after done or fail
});*/
});
You can see in the comment the version without the ajax manager. And it the same way to POST is like
this.DoPost = function (url, method, body, timeout) {
try {
body = JSON.stringify(body);
} catch (error) {
console.error(body);
return reject(error);
}
return new Promise((resolve, reject) => {
var options = {
type: 'POST',
url: url + method,
data: body,
contentType: "application/json",
dataType: 'json',
timeout: (15 * 1000) // sets timeout to 60 seconds
};
if (timeout) options.timeout = timeout;
const errorCallback = function (error) {
console.error(error);
return reject(error);
};
const successCallback = function (data) {
return resolve(data);
};
options.error = errorCallback;
options.success = successCallback;
$.manageAjax.add("default-queue", options);
/*$.ajax(options)
.done(function (data) {
return resolve(data);
})
.fail(function (error) {
console.error(error);
return reject(error);
})
.always(function () {
// called after done or fail
});*/
});
}//DoPost
The important thing here is the name of the ajax queue when adding a new GET / POST request via the api
$.manageAjax.add("default-queue", options);
This means basically that you can have one or more queues, that improves your requests parallelism.

Resources