Reputation: 673
I have an object constructor:
function Context(tid) {
this.tid = tid;
var self = this;
//We get all the data we need from the server to use in this Context.
$.post(
'/review/context/get_context',
{tid: tid},
function(data) {
results = $.parseJSON(data);
if(results.status == "SUCCESS") {
self.obj = results.object;
self.currenttodo = results.tid
}
}
);
}
I want to initiate that on a document load, and use that object, until and event triggers the object to be changed, at which point I want to wipe that object and re-initiate it with info from a different ajax call. It's desirable to use an object here because there is a boatload of functions that apply to all Contexts.
$(document).ready(function() {
cc = new Context($('#context-tabs').attr('name'));
console.log(cc);
console.log(cc.currenttodo);
}
generates the following console output:
Context
currenttodo: 14
obj: Object
tid: "1"
__proto__: Context
undefined
I think this is a standard case of this being an asynchonous function not being complete before execution of subsequent function, but I have a few questions:
1) Why can I see the value of cc.currenttodo in the console.log directly before the console.log where I can't access it? 2) Why is the Chrome console.log output different for two integers. The 14 is not in quotes and blue, and the tid: "1" is red and in quotes. I presume that indicates that tid is a string, but I want to confirm that. 3) How, if I can't use asynchronous calls in this manner would I instantiate a unique object for use in the calling $document.ready() function populated from a server call? I would think I would need to do it through the success: function, but can't seem to get anything except self.variables out of there?
Thanks in advance.
UPDATE: SO won't let me answer my own questions yet, so here is the working code:
function Context(tid) {
this.tid = tid;
var self = this;
//We get all the data we need from the server to use in this Context.
$.ajax({
url: "/review/context/get_context",
type: "POST",
data: "tid="+self.tid,
async: false,
dataType: "json",
success: function(data) {
if(data.status == "SUCCESS") {
self.obj = data.object;
self.currenttodo = data.tid;
}
}
});
}
Upvotes: 2
Views: 1015
Reputation: 673
Code sample that works to instantiate the above object. As pointed out, async: false is the key, otherwise you can't bubble the results of an AJAX call out to an instantiating object inside of a constucter
function Context(tid) {
this.tid = tid;
var self = this;
//We get all the data we need from the server to use in this Context.
$.ajax({
url: "/review/context/get_context",
type: "POST",
data: "tid="+self.tid,
async: false,
dataType: "json",
success: function(data) {
if(data.status == "SUCCESS") {
self.obj = data.object;
self.currenttodo = data.tid;
}
}
});
}
Upvotes: 0
Reputation: 399
1) Presuming you're clicking in the console to inspect the object, it's because by the time you're clicking, the call is complete and Chrome is nice enough to figure out what you were trying to see. The console.logs happen immediately though, so immediately requesting cc.currentodo means it doesn't know at that time.
2) Correct: "1" is a string. Check the JSON response and see what it is sending to confirm.
3) You can either use the success function, or run the POST synchronously. I would say keep working at the former. Generally getting a handle on async timing is tricky, but once you have it working it's quite powerful.
Upvotes: 1