I made a JS script which I plan to use as a sort of state object for getting a bunch of user information from different places. A lot of those places will be from other queries.
The issue is that the query seems to run as I can see the query status message, and the state of that query has the information I need. However, I am trying to set the return of that data to an object property, but it keeps coming up as undefined. Is there a huge time difference between when an object is instantiated and when a .trigger()
might fire?
Here is my code
function UsrObj(row) {
this.name = function() {
return row.name ? row.name : '';
}();
////
this.stripeCustId = function() {
GetCustomerId.trigger({
onSuccess: function (data) {
return data.customer_id;
}
});
}();
///
}
The other properties are filled, so I believe that logic is correct. Help would be greatly appreciated!
Hi @georgeoffley, I'm not sure I fully understand your question here. Would you be able to share how you're using this script and specify what exactly isn't defined and where it is that it's undefined?
Hello @everett_smith, thanks for getting back to me. I found another solution, but I was looking to get the return data for queries and save them as object properties. However, I discovered that saving the return within variables inside of functions can be pretty hit or miss.
I found the simpler way was to utilize the onSuccess
properties to set the data inside of a temporary state.
I suppose my remaining question is how is the best way to make sure data is coming back? For example if I have this snippet:
stripeCustId = function() {
GetCustomerId.trigger({
onSuccess: function (data) {
return data.customer_id;
}
});
};
How can I make sure that information came back so I can run the next step? If I use the code below sometimes the condition runs and sometimes it doesn't.
if (stripeCustId):
// run next part of logic
Let me know if all that makes sense.
Hi @georgeoffley, Without seeing the entire script you have currently, I'm not sure why you're seeing that behavior. From what you shared, I would expect that the // run next part of logic
would always run since stripeCustId
looks like it should be defined based on the top snippet where it's defined as a function.
If you wanted to trigger GetCustomerId and only run a piece of the script when GetCustomerId returns data with a defined customer_id property, I would suggest some code like this:
\
let stripeCustId = await GetCustomerId.trigger()
if(stripeCustId.customer_id){
//Do stuff
console.log(stripeCustId)
}
JS queries in Retool are async at the top level so you can use await outside of explicitly async functions. In the above code, GetCustomerId.trigger()
returns a promise that resolves to the data property of the triggered query (Retool's docs on .trigger) and the await operator "returns the fulfilled value of the promise" (MDN's docs on await). So stripeCustId will be defined as the data property of GetCustomerId, once GetCustomerId returns a result and the promise, GetCustomerId.trigger()
, is fulfilled.
Alternatively, if you just wanted to run some code when GetCustomerId succeeds and other code when it fails, you could define functions containing the code to be run in each scenario, and add them as the onSuccess and onFailure options for GetCustomerId.trigger()
. That could look something like this:\
function triggerGetCustomerId() {
}\
GetCustomerId.trigger({\
onSuccess: function(data) {\
// Do something with data when GetCustomerId succeeds
},
onFailure: function(error) {
// Do something with error when GetCustomerId fails
}\
})