How I do initial JavaScript Ajax initialization? - javascript

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

Related

reusable ajax and javascript function in CSHTML(RAZOR)

Im new in js and razor,part of my code should be repeated and this imposed more lines of code to my project,it could be nice if i can make it reusable,for example Ajax,where should i create a ajax to a specific URL to just call it when i need?in a separated razor file?in the following code,i have two click events and my ajax call and url is repeating,i want to get rid of this repeat:
function seriesClick(e) {
var _clicketBarChart = e.series.categoryField;
$.ajax({
dataType: "json",
type: "POST",
url: "#Url.Action("faultstatistics","Dashbrd")",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ "name": _clicketBarChart }),
success: function (result) {
faultstatChart(result);
}
});
function changeEvent(e) {
var _clicketCellGrid = e.categoryCell;
$.ajax({
dataType: "json",
type: "POST",
url: "#Url.Action("faultstatistics","Dashbrd")",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({"name": _clicketCellGrid }),
success: function (result) {
faultstatChart(result);
}
});
}
You have to create single method that can handle two situations, please refer to this example (based on your):
var ajaxHandler = function(targetName) {
$.ajax({
dataType: "json",
type: "POST",
url: "#Url.Action("faultstatistics","Dashbrd")",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({"name": _clicketCellGrid }),
success: function (result) {
faultstatChart(result);
}
});
}
var seriesClick = function(e) {
var targetName = e.series.categoryField;
ajaxHandler(targetName);
}
var changeEvent = function(e) {
var targetName = e.categoryCell;
ajaxHandler(targetName);
}

AJAX GET returns undefined on the first call, but works on the second one

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

Ajax method to a webmethod in asmx is not firing

I have a strange problem with the below AJAX jQuery method to call a webmethod in an asmx service. It's not firing when I try to call it, but the moment I uncomment any of the alert in code to debug, it works all of sudden.
It confuses me, what would be the problem? Am I missing something here..
Code:
var endXsession = function() {
var fwdURL = "";
$.ajax({
type: "POST",
url: "Session.asmx/RemoveSession",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msge) {
//alert(msge.d);
fwdURL = msge.d;
},
error: function(response) {
//alert(response.responseText);
fwdURL = response.responseText;
}
});
//alert(fwdURL);
return fwdURL;
};
response.responseText is undefined ... it's response.statusText ..
function endXsession() {
var fwdURL = "";
$.ajax({
type: "POST",
url: "Session.asmx/RemoveSession",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msge) {
// alert(msge.d);
fwdURL = msge.d;
}
,
error: function (response) {
// alert(response.statusText);
fwdURL = response.statusText;
}
});
// alert(fwdURL);
return fwdURL;
}
console.log(endXsession());

knockoutjs call keeps executing, how can I call it only once?

I have this piece of code:
t._teacherOptions = ko.observable();
function getTeacherList() {
$.ajax({
type: "POST",
url: "/webservices/Service.asmx/GetTeachers",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(i) {
if (i.d) {
console.log(i.d);
return t._teacherOptions(i.d);
}
},
error: function(n) {
u(n);
}
});
}
t.TeacherOptions = ko.computed(function() {
getTeacherList();
return t._teacherOptions();
});
And then my html:
<select data-bind="options: $root.TeacherOptions(), value: Id, optionsText: 'Name'"></select>
For some reason, when the page is opened, the function for getting the teacher list is continuously looping without stop.
I'm able to get the results I need but the loop keeps going and I need to stop that. Anything wrong I'm doing here?
You're looping endlessly because your TeacherOptions (which is a computed) accesses _teacherOptions (hence creating a dependency) and since you're mutating the value of _teacherOptions in the success callback of your Ajax call, the TeacherOptions is being evaluated again (because it depends on _teacherOptions) and issues the Ajax request again.
Try to call getTeacherList() outside of your computed:
t._teacherOptions = ko.observable();
function getTeacherList() {
$.ajax({
type: "POST",
url: "/webservices/Service.asmx/GetTeachers",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(i) {
if (i.d) {
console.log(i.d);
return t._teacherOptions(i.d);
}
},
error: function(n) {
u(n);
}
});
}
getTeacherList();
t.TeacherOptions = ko.computed(function() {
return t._teacherOptions();
});
See Documentation

Ajax/PythonBottle/Jquery/JSON trouble passing params

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

Categories

Resources