Declare a javascript object. Then set properties with jQuery and Ajax - javascript

I can't access the attribute of an instantiated class. The attribute is set using an AJAX call.
I am trying to define the class "CurrentUser", and then set the attribute "userId" using AJAX.
Here I define the class CurrentUser, and give it the attribute userID:
function CurrentUser() {
// Do an ajax call to the server and get session data.
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
this.userId = data.userId;
console.log(data.userId); // This will correctly output "1".
}, "JSON");
}
Here I instantiate a CurrentUser named billybob. Notice how I can't output billybob's attribute:
// Instantiate the user.
var billybob = new CurrentUser();
console.log(billybob.userId); // This will incorrectly ouput "undefined".
I've checked the common errors with AJAX:
The AJAX call returns the data correctly as a JSON object. I can read the correct object in Firebug / Network console. The AJAX call also has a status of "200" and "OK".
I can log the AJAX call's data correctly, as seen in the first part of my code where I log data.userId.

Maybe this clears it out:
In your original code:
function CurrentUser() {
// Do an ajax call to the server and get session data.
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
this.userId = data.userId;
console.log(data.userId); // This will correctly output "1".
}, "JSON");
}
You are creating an anonymous function on the fly, that will be later called by jQuery's internals with this
set to an ajax object. So this will be the ajax object inside the anonymous function, not billybob. So when
you do this.userId = ... this means the ajax object which doesn't have a userid property.
jQuery will have no idea where you got your callback function from, so it cannot set the this automagically
for you.
What you must do is to save the billybob (or any CurrentUser instance) reference and use it in the callback like so:
function CurrentUser() {
var self = this;
$.get("../../build/ajaxes/account/get_user_object_data.php", function(data) {
self.userId = data.userId; //self refers to what this refered to earlier. I.E. billybob.
console.log(data.userId, self.userid); // This will correctly output "1".
}, "JSON");
}
Also note that:
var billybob = new CurrentUser();
console.log(billybob.userId);
By the time you call console.log (I.E. instantly after creating billybob), the ajax request hasn't been completed yet so it is undefined.

In constructor, consider doing
var self = this;
and in function
self.userId = data.userId;
this inside function will be different than outside. Although, I don't know JQuery. May be it's supposed to set up closure automatically.

Related

Exception when calling a self-executing function in an object literal

I'm trying to set a field's value to a function, then execute it. this.fetchLocalStorage is not a function is what I get from running it.
var app = {
busdata: (function(){return this.fetchLocalStorage()})(),
fetchLocalStorage: function() {
//fetching
return "fetching data...";
}
};
console.log(app.busdata);
Note that by not making it a self-executing function, it works, but then it would mean the function is called everytime when I only need to fetch the data one time.
busdata: function(){return this.fetchLocalStorage()}
/* ... */
console.log(app.busdata()); //this calls the function every time :(
Thought it might a context problem so I tried a couple things with bind and call but with no luck.
Am I missing something?
this is only bound to the object when you call a method of the object, i.e. app.someMethod(). But you're trying to call fetchLocalStorage() when you're creating the object, not in a method of the object, so this is whatever the outer context is, which is likely the global window object.
You can't refer to other properties of the object until after the object has been created. So just call the function normally after you create the object.
var app = {
fetchLocalStorage: function() {
//fetching
return "fetching data...";
}
};
app.busdata = app.fetchLocalStorage();
I think your params were on the wrong side of the brace.
busdata: (function(){return this.fetchLocalStorage()}() ),

How to store $.getJSON object in global variable and navigate through it later

I'm experimenting with JQuery and trying to create a function to get dynamic data from a JSON returned API and store it in a global variable (I don't know if this is the right/best way to do this).
What I have so far is
function getdata(url){
var data = $.ajax({
type: 'GET',
url: url
});
return data;
};
So far everything works fine, but this returns an object with a "responseJSON" key and I can't seem to find a way to navigate to this key and then do a $.each loop through the arrays in it.
So the questions are:
Is this the right / way ( if not please explain your answer)
How do you navigate through a multidimensional object containing arrays in the "responseJSON" key.
Another approach is to pass a callback to your function so you can set the response handler within the function and less code when you call your getData method
function getdata(url, callback){
var data = $.ajax({
type: 'GET',
url: url
}).done(callback).error(function(){
alert('Oppps...something went wrong')
});
return data;
};
getData('urlstring', function(data){
/* doSomething with data */
})
AJAX is asynchronous. That means it runs in the background while the rest of your script runs. At a point in the future when the AJAX call completes, then you can access it.
In jQuery, $.ajax returns a promise. So what you can do is the following:
getdata('/path/to/your.json').done(function(data){
// Use your JSON data here
console.log(data);
});
What happens is that once the AJAX call is done, your .done() function will run and you will have access to the data returned.
Don't try to access the properties of the $.ajax object (the responseJSON won't be populated until the call is finished). Use callbacks to get at the returned data.
If you want the json data to be in global scope, just define a global variable (that is, outside the function), and then in the function fill it with the returned data. Something like so:
var api_response;
function get_data(url) {
$.post(url, function(j) { api_response = j; }, "json");
// or
$.getJSON(url, function(j) { api_response = j; });
}
You don't even need to create a function for this and can use jquery's own $.getJSON (the or case).

jQuery function execution order

I am having a problem, or perhaps a lack of understanding, with the jQuery execution order of $.get() function. I want to retrieve some information from a database server to use in the $.ready() function. As you all know, when the get returns, it passes the data to a return handler that does something with the data. In my case I want to assign some values to variables declared inside the ready handler function. But the problem is, the return handler of $.get() does not execute until after ready has exited. I was wondering if (a) am I doing this right/is there a better way or if (b) there was a way around this (that is, force the get return handler to execute immediately or some other fix I'm not aware of). I have a feeling this is some closure thing that I'm not getting about JavaScript.
As per request, I'll post an example of what I mean:
$(function() {
var userID;
$.get(uri, function(returnData) {
var parsedData = JSON.parse(returnData);
userID = parsedData.userID;
});
});
So as you can see, I'm declaring a variable in ready. Then using a get call to the database to retrieve the data needed. Then I parse the JSON that is returned and assign the userID to the variable declared before. I've tested it with a couple alerts. An alert after the get shows userID as undefined but then an alert in get's return handler shows it to be assigned.
$.get() is asynchronous. You have to use a callback to fill your variable and do the computation after the request is complete. Something like:
$(document).ready(function(){
$.get( "yourUrl", function( data, textStatus, jqXHR ) {
var myData = data; // data contains the response content
// perform your processing here...
registerHandlers( myData ); // you can only pass "data" off course...
});
});
// your function to register the handlers as you said you need to.
function registerHandlers( data ) {
// registering handlers...
}
$.get is an ajax request. A in AJAX stand for asynchronous, so script won't wait for this request to finish, but instead will proceed further with your code.
You can either use complete callback or you can use $.ajax and set async to false to perform synchronous request.
The $.get() function executes an async httprequest, so the callback function will be executed whenever this request returns something. You should handle this callback outside of $.ready()
Maybe if you explain exactly what do you want to do, it would be easier to help!
Are you looking for something like:
$(document).ready(function(){
var variable1, variable 2;
$.get('mydata.url', function(data){
variable1 = data.mydata1;
variable2 = data.mydata2;
});
});
If you declare the variables first, then you can set their values within the get call. You can add a function call at the end of the get handler to call a separate function using these values? Without some kind of example, its hard to go into any more detail.
Without seeing the full code, my guess is that you should declare your variable outside $.ready; initialize it in ready for the initial page load; then update it from the get callback handler.
for example
var x = ""; // declaration
$(document).ready(function() { x = "initial value"; });
$.get(...).success(function() { x = "updated from ajax"; });

javascript Scope issue in Ext.Ajax.request

I have this class which automatically generates JSON stores from server. Stores are created on the fly and are viewable in Firebug's DOM.
I think i have some scope issues.When i want to console.log(Ext.getStore('AdminSettings')) (which AdminSettings is one of the created stores) inside Ext.Ajax.request`s callback function, 'AdminSettings' store is returned but if i put console.log(Ext.getStore('AdminSettings')) everywhere outside callback function,i get undefined message in firebug and my store is not instantiated.
See code comments to see it in action.
Ext.Ajax.request({
url : './account/getadminstores',
callback : function(options, success, response) {
var json = Ext.decode(response.responseText);
var adminStores = new Array();
// setup and intitialize on the fly stores
for ( var key1 in json) {
var storeFields = new Array();
for ( var key2 in json[key1]) {// if (i==1){break;}
for ( var key3 in json[key1][key2]) {
storeFields.push(key3);}
break;};
Ext.define('MA.store.' + key1, {
extend : 'Ext.data.Store',
fields : storeFields,
storeId : key1,
data : json[key1]
});
Ext.create('MA.store.'+key1);};
console.log(Ext.getStore('AdminSettings'));
//returns MA.store.AdminSettings in firebug and everything is fine
}
});//eof Ext.Ajax.request
console.log(Ext.getStore('AdminSettings'));
//returns undefined which is strange
Ext.Ajax.request is asynchronous. Your final console.log call returns nothing because at the time it is executed the request has not yet completed. Any code depending on the results of the request's callback will need to be executed by the callback as well.
This is due to the asynchronous nature of javascript, callback doesn't get called until after the ajax request finishes, so the Ext data store doesn't get defined either.
The order of execution of your script is:
Ajax request is initialized
console.log is executed (undefined since the datastore hasn't been defined yet)
javascript is waiting for an ajax response from ./account/getadminstores
response comes in, callback function is called (which defines the data store)

Accessing javascript variables set in Callback function of a PageMethod call

In a click event, I invoke a PageMethods request, which contains two callback functions: OnServerValidationSuccess and OnServerValidationFailure. I also try and set create an object called clientResult;
var clientResult = { rc: "", msg: "" };
$('#btnSave').click( function () {
PageMethods.ServerValidateCreateCompany(companyName, domainName, country, OnServerValidationSuccess, OnServerValidationFailure);
alert(clientResult.rc); //this is null!
});
In the OnServerValidationSuccess, the result parameter contains the asynchronous response. And in there I try to assign it to clientResult.
//On Success callback
function OnServerValidationSuccess(result, userContext, methodName) {
clientResult = result;
if (clientResult.msg.length != 0) {
document.getElementById('resMsg').innerHTML = clientResult.msg;
$('#resMsg').addClass('warning');
}
}
I assign the result to local clientResult variable in the callback function. It should contain the fully formed server response, which is sent correctly by the server-side WebMethod.
However, it remains null or empty after PageMethod is called.
What must I do in order to assign the variable set in the callback to a local variable so that I can access it?
You seem to be assigning the value to clientResult correctly, you're just accessing it too early.
You're making an asynchronous/non-blocking call which means that it returns immediately but continues to work in the background. So your JavaScript immediately returns from the call to PageMethods.ServerValidateCreateCompany and moves on to the alert. But your request hasn't had time to complete and your success callback (OnServerValidationSuccess) hasn't even run yet so you get undefined or null.
You should invoke whatever function is going to process the response in the OnServerValidationSuccess function which is where the response will be received. Perhaps something like this (you already seem to doing something with msg, just move your work with rc here as well)
//On Success callback
function OnServerValidationSuccess(result, userContext, methodName) {
clientResult = result;
alert(clientResult.rc); //this will work
process(clientResult); //process the response here
if (clientResult.msg.length != 0) {
document.getElementById('resMsg').innerHTML = clientResult.msg;
$('#resMsg').addClass('warning');
}
}

Categories