I have been banging my head against this for a while now and I can't figure it out.
I have main.js who instantiates a user object and console logs a value from it.
main.js
jsUser = new user();
console.log(jsUser.passTimes);
I then have the user.js file, which houses the class and gets the data for passTimes
user.js
class user{
// construct the object
constructor(obj){
// just set stuff up, cuz why not?
this.pTimes = [];
}
loadPTimes(){
// return a promise
return new Promise((res,rej)=>{
$.ajax({
url: './data/importantfile',
type: 'post',
dataType: 'json',
data: {
method: 'getData',
termCode: termCode
},
success: (data)=>{
// trigger the resolve
res({
data: data,
class: this
});
}
});
});
}
get passTimes(){
// if pTimes is empty, or gone for some reason, do the following
if(
this.pTimes === undefined ||
this.pTimes.length == 0
){
// go get that promise and do stuff
this.loadPTimes().then((obj)=>{
// mom always told me I have value, and now I can prove it
this.pTimes = obj.data;
// send me up the chain
return this.pTimes;
});
}else{
// I always had value :), great send me up
return this.pTimes;
}
}
}
Easy enough right? However, when the page actually loads the console.log triggers while the promise/ajax is still running and returns undefined. Not what I was expecting.
What I was trying to do is, if the get function is triggered and we have no established value; go get the data using ajax and wait for that data to come back before return something.
I have rewritten this so many different ways with different results, but not the result I was looking for (console.log returns the actual ajax results).
I was hoping someone here has used a similar pattern, or a better one. That waits for data before returning.
Edited:
Maybe my questions was written clearly enough. I need ajax data, when the class is constructed or when the get function is called. It has to be there.
It can't be asynchronous because that data is needed almost immediately. So I throw the request in a promise, expecting the promise to be respected and the get function to return when it has data.
This is not happening, instead get is returning undefined as a value while the ajax request is still waiting for a reply.
This should fix your problem:
class user{
// construct the object
constructor(obj){
// just set stuff up, cuz why not?
this.pTimes = [];
}
loadPTimes(){
// return a promise
return new Promise((res,rej)=>{
$.ajax({
url: './data/importantfile',
type: 'post',
dataType: 'json',
data: {
method: 'getData',
termCode: termCode
},
success: (data)=>{
// trigger the resolve
res({
data: data,
class: this
});
}
});
});
}
get passTimes(){
return (async () => {
// if pTimes is empty, or gone for some reason, do the following
if(
this.pTimes === undefined ||
this.pTimes.length == 0
){
// go get that promise and do stuff
const obj = await this.loadPTimes();
// mom always told me I have value, and now I can prove it
this.pTimes = obj.data;
// send me up the chain
return this.pTimes;
}else{
// I always had value :), great send me up
return this.pTimes;
}
})();
}
}
passTimes will return a promise so to get the value you must use await or then/catch closure