When this AJAX request POSTS, the newUser() function says no arguments are being passed, even though i have the userInput and passInput fields filled out. The JS/JQ/AJAX:
var userInput = document.getElementById('registerUsername');
var passInput = document.getElementById('registerPassword');
var message = document.getElementById('checkUsernameMessage');
$(document).ready(function() {
$('#submitRegisterButton').click(function () {
$.ajax({
type: "POST",
url: "/newUser",
data: JSON.stringify({"username":userInput, "password":passInput}),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (msg) {
$('#checkUsernameMessage').text(msg.d);
}
});
});
});
And my python bottle function newUser() :
#post('/newUser')
def newUser(username, password):
etc..
You need to nest your selectors within your dom ready call. Right now they are running before the DOM is ready, and are thus returning undefined. You can verify this by consoling the variables to see if they return any data.
The other thing, is you probably want to select the value of these inputs, and not return the DOM elements themselves: so instead, try
var userInput = document.getElementById('registerUsername').value etc.
$(document).ready(function() {
$('#submitRegisterButton').click(function () {
var userInput = document.getElementById('registerUsername').value;
var passInput = document.getElementById('registerPassword').value;
var message = document.getElementById('checkUsernameMessage').value;
$.ajax({
type: "POST",
url: "/newUser",
data: JSON.stringify({"username":userInput, "password":passInput}),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (msg) {
$('#checkUsernameMessage').text(msg.d);
}
});
});
});
This should fix your issue.
With the clientside issue fixed, the python issue was:
The post request was being called as: def newUser( username, password ) where there should have been no arguments passed in, but derived from the form variable:
def newUser():
username = request.forms.get('userInput')
password = request.forms.get('passInput')
message = request.forms.get('message')
Related
I'm pulling information with ajax. I want it my document.ready function(ajax) starting first because knockout file starting first and my "var initialData" value going null. How my Ajax start first ?
Here is my F12 Source
My script:
<script type="text/javascript">
var initialData;
function functionViewModel() {
$(document).ready(function () {
$.ajax({
type: "POST",
url: "KnockoutGrid2.aspx/GonderUrunler",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log(msg.d);
initialData = msg.d;
}
});
});
var fn = {
friends: ko.observableArray(initialData)
};
fn.removeUser = function (item) {
fn.friends.remove(item);
};
return fn;
};
ko.applyBindings(functionViewModel());
</script>
Update 2
The answer of #user3297291 is better than mine, because is Knockout who handles all the state of this form. Please, don't do the applybindings in the answer of the ajax request.
The user need to know that the data isn't loaded yet, and this can be handled with knockout.
Original answer
Perhaps if you move the initialization of Knockout inside the success function:
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "POST",
url: "KnockoutGrid2.aspx/GonderUrunler",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log(msg.d);
initialData = msg.d;
// All initialization inside the 'success' function
function functionViewModel(initialData) {
var fn = {
friends: ko.observableArray(initialData)
};
fn.removeUser = function (item) {
fn.friends.remove(item);
};
return fn;
};
ko.applyBindings(functionViewModel(initialData));
}
});
});
</script>
You could show a div with the message: "loading data...".
And when success run, hide this div.
Update 1
After your comment, I don't know why you need the return fn. I propose this solution:
<script type="text/javascript">
// Updating 'functionViewModel()' to add 'self'.
// Move functionViewModel()' outside ajax response
function functionViewModel(initialData) {
var self = this;
self.friends = ko.observableArray(initialData);
self.removeUser = function (item) {
self.friends.remove(item);
};
};
$(document).ready(function () {
$.ajax({
type: "POST",
url: "KnockoutGrid2.aspx/GonderUrunler",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log(msg.d);
initialData = msg.d;
// All initialization inside the 'success' function
ko.applyBindings(functionViewModel(initialData));
}
});
});
</script>
Here I'm using self ( see Managing ‘this’ ) and don't return fn, because Knockout handles its state.
Use async:false in your code
$.ajax({
type: "POST",
url: "KnockoutGrid2.aspx/GonderUrunler",
data: "{}",
async : false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
console.log(msg.d);
initialData = msg.d;
}
});
You do not want to wait with applyBindings until your ajax response is handled... Your document will look ugly if you let knockout wait with applying bindings and your users will have nothing to look at.
What you should do:
Apply bindings as soon as $(document).ready triggers
Make sure your viewmodels use observable properties that allow you to easily inject data later on
Make sure you define some sort of loading state to show your users the data is being downloaded
I.e.:
function functionViewModel() {
var friends = ko.observableArray([]);
var loading = ko.observable(true);
var removeUser = function(user) {
friends.remove(user);
}
// Get the data and write it to an observable property once done
$.ajax({
type: "POST",
url: "KnockoutGrid2.aspx/GonderUrunler",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
friends(JSON.parse(msg.d));
loading(false);
}
});
return {
friends: friends,
loading: loading,
removeUser: removeUser
};
};
$(document).ready(function() {
ko.applyBindings(functionViewModel());
});
Once again I've been beating my head against the wall, trying to pull this part of returned data from ajax to a variable outside the function.
When I return the value it always comes up undefined when I alert() inside it shows the proper values.
function getItemInfo(itemHashPass) {
$.ajax({
url: 'index.php//Welcome/getItem', //This is the current doc
type: "POST",
data: 'iHash='+itemHashPass,
dataType: "json",
async: false,
success: function(data){
return data.Response.data.inventoryItem.itemName;
}
});
}
I've also tried
function getItemInfo(itemHashPass) {
var tmp = null;
$.ajax({
url: 'index.php//Welcome/getItem', //This is the current doc
type: "POST",
data: 'iHash='+itemHashPass,
dataType: "json",
async: false,
success: function(data){
tmp = data.Response.data.inventoryItem.itemName;
}
});
return tmp;
}
Like Jonathan said you should write your business logic in the callback or you can try Deferred syntax. In this case it will looks like
function yourBusinnesLogicFunction() {
...
getItemInfo("password_hash_value").done(
function(data){
alert(data.Response.data.inventoryItem.itemName);
}
)
}
function getItemInfo(itemHashPass) {
var tmp = null;
return $.ajax({
url: 'index.php//Welcome/getItem', //This is the current doc
type: "POST",
data: 'iHash='+itemHashPass,
dataType: "json",
async: false,
})
}
I am working on a real estate web app in ASP.NET MVC. My problem is in my Reservations section.
I am using AJAX to post in a Controller which returns a JSONResult. Here is my code:
Controller
[HttpPost]
public JsonResult SubmitReservation(ReservationViewModel rvm)
{
return Json(rvm, JsonRequestBehavior.AllowGet);
}
Main AJAX
var rvm = new ReservationViewModel();
getBuyerInfo(rvm.SelectedBuyerID, clientCallback);
getSiteInfo(rvm.SelectedSiteID, siteCallback);
getUnitInfo(rvm.SelectedUnitID, unitCallback);
$.ajax({
url: "/Reservations/SubmitReservation",
data: JSON.stringify(rvm),
type: "POST",
dataType: "json",
contentType: "application/json",
success: function () {
console.log(clientData);
console.log(siteData);
console.log(unitData);
//Assignment of data to different output fields
//Client Data
$('#clientName').html(clientData.FullName);
$('#clientAddress').html(clientData.Residence);
$('#clientContact').html(clientData.ContactNumber);
//Site Data
$('#devSite').html(siteData.SiteName);
$('#devLoc').html(siteData.Location);
////House Unit Data
$('#unitBlock').html(unitData.Block);
$('#unitLot').html(unitData.Lot);
$('#modelName').html(unitData.ModelName);
$('#modelType').html(unitData.TypeName);
$('#lotArea').html(unitData.LotArea);
$('#floorArea').html(unitData.FloorArea);
$('#unitBedrooms').html(unitData.NumberOfBedrooms);
$('#unitBathrooms').html(unitData.NumberOfBathrooms);
$('#unitPrice').html(unitData.Price);
$('#reservationDetails').show();
alert("Success!");
},
error: function (err) {
alert("Error: " + err);
}
});
Functions for fetching data
function getBuyerInfo(id, cb) {
$.ajax({
url: "/BuyersInformation/GetBuyerByID/" + id,
type: "GET",
contentType: "application/json",
dataType: "json",
success: cb
});
}
function getSiteInfo(id, cb) {
$.ajax({
url: "/Sites/GetSiteByID/" + id,
type: "GET",
contentType: "application/json",
dataType: "json",
success: cb
});
}
function getUnitInfo(id, cb) {
$.ajax({
url: "/HouseUnits/GetUnitByID/" + id,
type: "GET",
contentType: "application/json",
dataType: "json",
success: cb
});
}
function ReservationViewModel() {
var buyerId = $('#SelectedBuyerID').val();
var siteId = $('#SelectedSiteID').val();
var unitId = $('#SelectedUnitID').val();
var rsvDate = $('#ReservationDate').val();
var me = this;
me.ReservationDate = rsvDate;
me.SelectedBuyerID = buyerId;
me.SelectedSiteID = siteId;
me.SelectedUnitID = unitId;
}
function clientCallback(result) {
clientInfo = result;
clientData = clientInfo[0];
}
function siteCallback(result) {
siteInfo = result;
siteData = siteInfo[0];
}
function unitCallback(result) {
unitInfo = result;
unitData = unitInfo[0];
}
The whole code WORKS well for the second time. However, it does not work for the FIRST time. When I refresh the page and I hit Create, it returns undefined. But when I hit that button again without refreshing the page, it works well. Can somebody explain to me this one? Why does AJAX returns undefined at first but not at succeeding calls? Thanks in advance.
You are calling several ajax requests in your code, inside these functions:
getBuyerInfo(rvm.SelectedBuyerID, clientCallback);
getSiteInfo(rvm.SelectedSiteID, siteCallback);
getUnitInfo(rvm.SelectedUnitID, unitCallback);
and finally $.ajax({...}) after them, where you use results from pervious ajax calls.
Your problem is that the first ajax calls do not necessarily return results before your start the last ajax because they are all async. You have to make sure you get three responds before calling the last ajax. Use promises or jQuery when, like this:
var rvm = new ReservationViewModel();
$.when(
$.ajax({
url: "/BuyersInformation/GetBuyerByID/" + rvm.SelectedBuyerID,
type: "GET",
contentType: "application/json",
dataType: "json"
}),
$.ajax({
url: "/Sites/GetSiteByID/" + rvm.SelectedSiteID,
type: "GET",
contentType: "application/json",
dataType: "json"
}),
$.ajax({
url: "/HouseUnits/GetUnitByID/" + rvm.SelectedUnitID,
type: "GET",
contentType: "application/json",
dataType: "json"
})
).done(function ( clientResponse, siteResponse, unitResponse ) {
clientInfo = clientResponse;
clientData = clientInfo[0];
siteInfo = siteResponse;
siteData = siteInfo[0];
unitInfo = unitResponse;
unitData = unitInfo[0];
$.ajax({ ... }) // your last ajax call
});
AJAX calls are asynchronous. You last ajax call will not wait until your above 3 ajax calls finishes its work. so you can make use of $.when and .done here as below..
$.when(
getBuyerInfo(rvm.SelectedBuyerID, clientCallback);
getSiteInfo(rvm.SelectedSiteID, siteCallback);
getUnitInfo(rvm.SelectedUnitID, unitCallback);
).done(
$.ajax({
//Ajax part
})
);
I have a dropdown that has a list of ID's in it. The customer will select one and it will reflect a price total on the page. Im creating an ajax call that will update the total when a different ID is pulled from the Dropdown.
$("#BrandId").on('focus', function () {
// Store the current value on focus and on change
previous = this.value;
}).change(function () {
alert("Previous: " +previous);
sel = this.value;
alert("Selected: " +sel);
$.ajax({
cache: false,
type: "get",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("GetBrandCost", "Shocks")',
data: JSON.stringify({ idp: previous, id: sel }),
dataType: "json",
aysnc: false,
success: function (data1) {
alert(data1);
//ShockTotal = $("#ShockTotal").html();
//ShockTotal = ShockTotal / 1;
////ShockTotal = ShockTotal - data1;
//$("#ShockTotal").html(data1);
}
});
});
The alerts are working perfectly but the ajax isnt passing those ID's into the controller, the controller is just receiving nulls.
public decimal GetBrandCost(string idp, string id)
{
decimal costp = 0;
decimal cost = 0;
if (id == "" || id == null || idp == "" || idp == null)
{
return 0;
}
ShockBrand brandp = db.ShockBrands.Find(idp);
costp = brandp.Cost;
ShockBrand brand = db.ShockBrands.Find(id);
cost = brand.Cost;
cost = cost - costp;
return cost;
}
Since they are null I am hitting my if statement and just returning zero inside the success. Most of the things I read were to add the content type but that didnt seem to help in my case, Im sure it is something little.
From browser console, this
$.ajax({
cache: false,
type: "get",
contentType: "application/json; charset=utf-8",
url: 'http://google.com',
data: JSON.stringify({ idp: 1, id: 2 }),
dataType: "json",
aysnc: false,
success: function (data1) {
console.log(data1)
}
});
returns request to http://google.com/?{%22idp%22:1,%22id%22:2}&_=1440696352799, which is incorrect
and without stringify
$.ajax({
cache: false,
type: "get",
contentType: "application/json; charset=utf-8",
url: 'http://google.com',
data: { idp: 1, id: 2 },
dataType: "json",
aysnc: false,
success: function (data1) {
console.log(data1)
}
});
returns http://google.com/?idp=1&id=2&_=1440696381239 (see Network tab)
So don't use JSON.stringify
Why it's gonna work - your asp.net controller action receives simple typed parameters (string, numbers, etc) and jquery is fairly enought smart to determine what are going to send, if it was object inside object it will send it as POST data for POST, and string represenation of object for GET (you have GET request, but for purpose of knowledge, just stick with 2 types of data that can be send, params & data) So when jquery configures url, asp.net understands conventions, and matches request to approciated action
But Don't believe me, check it yourself
chrome dev console is your friend
By removing the
contentType: "application/json; charset=utf-8
and
dataType: "json"
it worked for me. Otherwise, I was always getting value = null in the controller action.
My code for calling ajax with data is now:
$(function () {
$.noConflict();
$.ajax({
type: "POST",
url: "../Case/AjaxMethodForUpdate",
data: {typ: $('#typeID').val()},
success: OnSuccess,
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
You can just put it like
var dataReq={ idp: previous, id: sel };
data: dataReq
And no need to use dataType and contentType.
I am using Angular Js with JQuery in a noodles way. See my code below.
Code
app.controller('ClassController', function ($scope) {
$scope.ShowHideNoRecords = false;
var credentials = new Object();
credentials.SourceName = "###";
credentials.SourcePassword = "###";
credentials.UserName = "###";
credentials.UserPassword = "##";
credentials.SiteId = [-99];
var locationIds = [1];
var startDate = Date.today();
var endDate = startDate;
var dto = { credentials: credentials, startDate: startDate, endDate: endDate, locationId: locationIds };
$.ajax({
type: "POST",
url: 'MbApiConnector.asmx/GetAllClasses',
data: JSON.stringify(dto),
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
success: function (response) {
alert(response.d);
},
complete: function (msg) {
$scope.$apply(function () {
$scope.Classes = JSON.parse(JSON.parse(msg.responseText).d);
if ($scope.Classes.length > 0) {
$scope.checkin = function (id) {
dto = { credentials: credentials, classId: id };
$.ajax({
type: "POST",
url: 'MbApiConnector.asmx/Checkin',
data: JSON.stringify(dto),
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
complete: function (msg) {
alert(msg.responseText);
}
});
}
}
else {
$scope.ShowHideNoRecords = true;
}
});
}
});
});
Everything is working fine with this code. I knew its a bad idea mixing the two but my app was already developed in Jquery Ajax and we are upgrading with Angular JS but with lesser changes. So I came up with this solution.
Anyways, my issues is that jquery ajax success function is not get called. I am able to receive data from the webservice , but inside the complete method, as you can see in the code above.
Can you explain me why its behaving so?
May be Jquery fails to parse it as the result may not be in JSON format, try to find the error using error callback function. You could try with dataType : 'json'.
error: function (err) { alert(err) }