I'm making my first steps with javascript objects combined with php objects. So far everything is working fine, but I struggle to access the javascript object created in the ajax success response outside of this function.
Here is my JS code:
function settings(mannstage, stundenlohn, tags) {
this.mannstage = mannstage;
this.stundenlohn = stundenlohn;
this.tags = tags;
}
var currentSettings;
SendAjaxJsonRequest("getSettings");
function SendAjaxJsonRequest(method, jsonObject) {
jsonObject = (typeof jsonObject === "undefined") ? "none" : jsonObject;
$.ajax({
type: "POST",
url: "app/class/controller/ajax.php",
data: {
method: method,
jsonObject: jsonObject
},
success: onSuccess
})
};
function onSuccess(content) {
var response = $.parseJSON(content);
currentSettings = new settings(response.mannstage, response.stundenlohn, response.tags);
console.log(currentSettings); //Returns the object
}
console.log(currentSettings); //This is undefined
The last console.log is undefined. How can I make currentSettingsaccessible outside the onSuccess function?
Thank you!
Ajax is asynchronous, so the last console.log will be executed before the success function is called.
currentSettings is accessible outside the onSuccess function, but your last console.log call runs immediately after onSuccess is defined, which is before it's been called, so the value of currentSettings is still undefined at that point.
Maybe editing your code like this will demonstrate it:
function onSuccess(content) {
var response = $.parseJSON(content);
currentSettings = new settings(response.mannstage, response.stundenlohn, response.tags);
console.log(currentSettings); //Returns the object
afterSuccess(); // Also returns the object
}
function afterSuccess() {
console.log(currentSettings);
}
Related
I am currently writing a small Javascript Object which will add click listeners onto certain elements which then trigger an AJAX call to a PHP function. This is all working fine however, I want to call a function when the AJAX responds. I have made this happen by passing a function to the AJAX call which will be triggered when the response is given.
The problem I am having is that I am losing the scope of the object when passing through the protoytype as a call back (in order to stop the aynschronous problems that can occur with AJAX calls). The 'this' object (or self) is set to the window and not the instance of the object I have created. Here is my code:
//Rating Submit
var Rater = function(element, videoId, ratingStars, userId) {
this.userId = userId,
this.element = element;
this.videoId = videoId;
this.ratingStars = ratingStars;
var self = this;
jQuery(this.ratingStars).click(function(e) {
e.preventDefault();
self.ratingClick(this, self.changeStar);
});
}
Rater.prototype.ratingClick = function(item, changeStar) {
jQuery.ajax({
type : 'post',
dataType : 'json',
url : 'api/rate-video',
data : "userId=" + this.userId + "&videoId=" + this.videoId + "&rating=" + jQuery(item).attr("data-score"),
success : function(data) {
changeStar(data, item);
}
});
}
Rater.prototype.changeStar = function(response, item) {
var maxCount = jQuery(item).attr("data-score");
//console.log(self);
jQuery(self.ratingStars).each(function(key, value) {
alert(key);
});
}
As you can see, I am passing the 'self.changestar' prototype function to the AJAX call for this to be called when a response is given. When I try and access any of the variable I set in the constructor for that particular instance though, it says it is the Window object and not an instance of the class. Is it possible to pass through a prototype function as a call back from within the instance? I hope I have explained myself ok....
Thanks
The problem is that when you do this:
self.ratingClick(this, self.changeStar);
you have exactly the same problem you had in Rating with the jQuery click callback, which you solved with your self variable: Only the function reference, changeStar, gets passed, nothing about what value to use as this when calling it.
One solution is to use Function#bind, which you call on a function to get back another function that, when called, will call the original with a specific this value (and optional arguments):
self.ratingClick(this, self.changeStar.bind(self));
Alternately, you could pass the value to use as this separately:
self.ratingClick(this, self.changeStar, self);
...and then use Function#call in the success handler:
Rater.prototype.ratingClick = function(item, changeStar, thisArg) { // <== Change here
jQuery.ajax({
type : 'post',
dataType : 'json',
url : 'api/rate-video',
data : "userId=" + this.userId + "&videoId=" + this.videoId + "&rating=" + jQuery(item).attr("data-score"),
success : function(data) {
changeStar.call(thisArg, data, item); // <=== And here
}
});
}
in arrayRec , onShow value should be a function.
Following is my reference code.
Any help?
This is my reference code:
if (rec.element_flag == '111'){
var arrayRec = [];
$.ajax({
type:'GET',
url: "/aps/one-url",
success: function(responseData){
for (var i = 0; i < responseData.length; i++){
var recJ;
var newFunction1 = function onshowdata(counter){
if(responseData[counter].fields.on_show_fn != null){
return function responseData[counter].fields.on_show_fn;
}
else
return;
}
recJ = {
element: responseData[i].fields.element_class,
placement: responseData[i].fields.placement,
title: responseData[i].fields.title,
content: responseData[i].fields.content,
onShow: newFunction1(i)
}
arrayRec.push(recJ);
console.log('-------arrayRec------');
console.log(arrayRec)
aps.walk.setupBootstrap(arrayRec);
}
},
error: function(){
alert('get failure');
}
});
}
Tried many ways but what I am missing?
in JSON, only text can be used, not objects. Functions are objects too. So, in JSON, name of the function can be passed, not the function object. An alternate way is to send the text of that entire function, which can be run using "eval", though this way is not recommended.
Use closure technique here. Define function above the ajax code, and use the name of the function inside it, which is a standard method of doing this.
I just want to use a variable from outside of the function, but I am not sure what I have to do for that...
Is var myRequest = a; line enough to use this variable in the function?
Because I saw such an example: var myRequest = e.which;
I am asking this because I did not get a succesful result for my request.
I am think that it is not working as I expected because ajaxFunction(3) working diffirent than writing send.php?goto=3 into address bar of my browser.
You can see the following codes:
function ajaxFunction(a)
{
var ajaxRequest;
try {
ajaxRequest = new XMLHttpRequest();
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Your browser broke!");
return false;
}
}
}
ajaxRequest.open("GET", "send.php?goto=" + a, true);
ajaxRequest.send();
}
If you want to use a variable outside a function you have to use a global scope variable, example (using jQuery ajax)
var globalA = null;
$(document).ready(function(){
var localA1 = null;
$.ajax({
"url":"http://someurl.com/",
"type":"POST",
"dataType":"json",
"success":function(incomingData){
var localA2 = incomingData //localA2 only useable inside this function
localA1 = incomingData; //localA1 being set here still can only be used here as code within the "ready" function has already been executed and will see it as null
globalA = incomingData; //Now any further code should use globalA as it now contains useable data
doSomethingWithData();
},
"error":function(xhr,msg) {
alert("Ajax Error:"+msg);
}
});
alert(localA1); //Will give alertbox with null in it as localA1 has not been set.
});
function doSometingWithData() {
alert(globalA); //You can now use the data in whatever function makes reference to globalA
}
Of course in this example you could have just passed the data straight to doSomethingWithData() and processed it there.
You could take a look at the jQuery $.globalEval for instantiating a variable globally inside of your AJAX success function.
$.ajax({
url: "send.php",
success: function (data) {
$.getScript("somescript.js", function(data) {
$.globalEval("var something = new Whatever;");
});
});
The $.getScript portion is a helpful little snippet if you find you need to load an external JS file in your ajax call, and make its assets globally available. You can then use $.globalEval to instantiate a variable inside of your AJAX function.
Documentation for $.globalEval
Documentation for jQuery AJAX
You don't a function wrapper for setting a value to a variable.
var myRequest = a;
That is good enough.
After thought revision
in a very basic way a variable can be created on its own like a place holder.
var myRequest;
when you get to the function (say you have a series of functions.
You could do something like this.
function(myRequest=a);
if the function has more than one argument it can look like this.
function(myRequest=a,myConcern=b); as you have it stated in the
var arg1 = 1;
var arg2 = 2;
var arg3 = 3;
ajaxRequest.open(arg1,arg2,arg3);
I hope this is helpful and yes, some more info would help (like the poster below stated).
I want to create a custom javascript object which contains data returned from a jQuery AJAX request, but I don't know which is the right way to do it. I was thinking maybe one way could be to include the AJAX request inside the constructor function so the object is created like this:
// Constructor function
function CustomObject(dataUrl) {
var that = this;
$.ajax(dataUrl, {
success: function (json) {
that.data = $.parseJSON(json);
}
});
}
// Creating new custom object
var myObject = new CustomObject('http://.....');
Another way may be to use a function which does the AJAX and then returns the new object based on the data from the AJAX response.
function customObject(dataUrl) {
// Constructor function
function CustomObject(data) {
this.data = data;
}
$.ajax(dataUrl, {
success: function (json) {
var data = $.parseJSON(json);
return new CustomObject(data);
}
});
}
// Creating new custom object
var myObject = customObject('http://.....')
I would like to know what is the best practice when doing something like this, as well as advantages/disadvatages of different methods. Maybe you can point me to some article or example on something similiar to what I am trying to do.
Thanks in advance.
I think this would be a better approach, it makes your CustomObject only knowledgeable about the data it contains. Here you delegate the work of creating objects to a factory, and pass in a callback to get a reference to the created object, since ajax is asynchronous. If you don't mind making it synchronous, then the createCustomObject function can just return the instance, and the callback can be removed.
function CustomObject(data) {
this.data = data;
}
var factory = (function(){
function create(dataUrl, objectClass, callback){
$.ajax({
url: dataUrl,
success: function (data) {
callback(new objectClass(data));
}
});
}
return{
createCustomObject: function(dataUrl, callback){
create(dataUrl, CustomObject, callback);
}
};
})();
// Creating new custom object
var myObject = null;
factory.createCustomObject('http://..', function(customObject){
myObject = customObject;
});
I'd argue that the second method is better because then you only create a new CustomObject once the script is actually fully prepared to do so (i.e. it has the data it needs from the AJAX request).
I'm trying to have a jQuery.getJSON() call change a global variable with the JSON array it returns:
var photo_info ;
//Advance to the next image
function changeImage(direction) {
jQuery('img#preview_image').fadeOut('fast');
jQuery('#photo_main').css('width','740px');
if (direction == 'next') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_next, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
} else if (direction == 'prev') {
jQuery.getJSON('/ajaxupdate?view&sort='+sort+'&a='+a+'&s=' + title_url_previous, function(data) {
photo_info = data;
title_url = photo_info.title_url;
title_url_next = photo_info.preview_title_url_next;
title_url_previous = photo_info.preview_title_url_previous;
});
}
}
However, the variable photo_info is only accessible from within the getJSON() function and returns undefined from anywhere else in the script.
What am I doing wrong?
as Randal said Ajax call is asynchronous. Use the ajaxComplete function or replace the getJSON function with an .ajax call and use the photo_info var whithin the success function e.g.:
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(photo_info);
}
});
If you're looking at photoinfo in the rest of the script right after changeImage has returned, then of course it won't have a value, because the Ajax call is asynchronous. You need to rethink your application to be more event driven.
JavaScript scoping isn't quite like standard scoping. It looks like you're actually losing your scope because of nested functions. Try giving this article a read:
http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/