setValue not working directly after selectRow

Could you share you app json? I can debug for you.

Thanks Anson.
What is the email address to share the app.

you can click my avatar and message me

I have sent it.

hello, I have not access to your app, I can't visit it. You can export it to json file and share it. But remember to remove sensitive information first.

Hi Anson,

On second thoughts I would rather not share the app because of the data in the app.
Do you have an advice for me?

Reyer

Hi Anson,

Using this modified version of the script solves the problem:
if (segmentedControlLicenser.value == 'Insert') {
tableLicenser.selectRow({mode:'index', indexType: 'display', index: 1});
await GetMaxID.trigger();
let max = GetMaxID.data[0].Max_Id;
const sleep = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));
await sleep(1000);
numberInputLicenserID.setValue(max);
}
Adding a 1 second delay is a solution.
This proves that timing is the issue.
I assume that the setValue worked correctly but the value in the numberInput component was then overwritten by the value from the selectedRow from the table.
Refreshing the data from a table appears to take more time than I expected.

It could be that 1 second delay is not always enough. I could use 2 or 3 seconds.
But my question now is: is there a better solution than using a sleep?

kind regards
Reyer

Hello, I create a app for your reference. and it work well in my demo.
you can import it to your app to check detail. It's some problem with async syntax you use in wrong way.

  tableLicenser.selectRow({mode:'index', indexType: 'display', index: 1});
  // you must assign the value return from await expression to a variable such as `temp`; if not, the GetMaxID in following `let max = GetMaxID.data[0].Max_Id;` statement will refer to promise instead of resolved value, this is the reason why you fail to get the max value;
  let temp = await GetMaxID.trigger();
  
  let max = temp.data[0].Max_Id;
  console.log('max = ' + max);
  numberInputLicenserID.setValue(max);
}

image

Here is app json, you can import it by this

setValue.json (19.4 KB)

Hi Anson,

Thanks for all the effort you have spent to help me. I appreciate that.
I copied your code and inserted it into my app.
Unfortunately it doesn't help. I still have the same problem.

Looking at your code example (that works) I see that your situation is a much different than mine.
The selectRow in my situation has a real database and that means the selectRow will take more time.
Also the GetMaxID.trigger in my situation is based on a real database.
I think that's why it's not quite comparable.

If there is no other solution I will use the sleep as I described in my previous post.

kind regards
Reyer

Hi Anson,

I tried to apply my "solution" in a second app.
To my disappointment it didn't work there, not even with a longer delay.,
So I was wrong.
I removed the selectRow and even without it I have the same problem. So the selectRow is not the problem.

Now my script is like this:
if (segmentedControlLicenserDetail.value == 'Insert') {
buttonLicenserUpdate.setDisabled(1);
buttonLicenserInsert.setDisabled(0);
numberInputLicenserID.setDisabled(0);
await GetMaxLicenserID.trigger();
//let temp = await GetMaxLicenserID.trigger();
console.log ('query completed');
textInputLicenserName.clearValue();
urlLicenser.clearValue();
let max = GetMaxLicenserID.data[0].Max_Id;
//let max = temp.data[0].Max_Id;
console.log ('Max = '+ max);
numberInputLicenserID.setValue(max+1);
}
My findings:
The first time the script runs I see in the State that the await GetMaxLicenserID.trigger(); has the correct result and the console shows query completed. Also the clearValue lines are excuted correctly. However the console does not show the second line console.log ('Max = '+ max).
That means that the script terminates during the execution of let max = GetMaxLicenserID.data[0].Max_Id;
When I execute the script a second time everything runs perfectly!!

So the big question is: what causes let max = GetMaxLicenserID.data[0].Max_Id; to terminate the script? I see no errors.

I also tried your version (commented out) but in that case the second run had the same result as the first one.

Any suggestion for a solution?

Reyer

[quote="AnsonHwang, post:11, topic:25051"]

  
if (segmentedControlLicenser.value == 'Insert') {
  tableLicenser.selectRow({mode:'index', indexType: 'display', index: 1});
    GetMaxLicenserID.trigger({onSuccess(data){
      let max = data.data[0].Max_Id;
        console.log(data);// pls share the screenshot of this object in console
        console.log('max = ' + max);
        numberInputLicenserID.setValue(max);
    }});
}

Hello Reyer, could you try it in this way again?

I don't know the detail of GetMaxLicenserID, so I have not idea about the debug.
Could you share the screenshot of data output in above code in console?

No, you should never use this solution, it can't ensure the same result in very runing.

Hi Anson,

There is nothing in the console.log.

Reyer

I have a similar case now when I want to check an existing ID in a table.
For that reason I have a simple query that counts the number of occurrences of that ID.
When I click the Insert button for inserting a new record I check the existence of an ID with this script to avoid a duplicate key value:

await CheckExistingContractID.trigger();
let num = CheckExistingContractID.data[0]['COUNT(ID)'] ;
console.log('num = '+ num);
if (num >0){
utils.showNotification({title: 'ContractID already exists', description : "" , notificationType : "error", duration: 6});
}

The first time I click there is no expected result in the console.log.
It shows:
image
The second time I see the expected result:
image

I hope somebody can help me.

Reyer

In the most recent example, does it work better if you refactor this example:

await CheckExistingContractID.trigger();
let num = CheckExistingContractID.data[0]['COUNT(ID)'] ;
console.log('num = '+ num);

to

let num = await CheckExistingContractID.trigger();
console.log('num = '+ num);

There's a related post here that talks about an advanced setting on JS queries that can help with keeping track of updated values.

Generally speaking, I'd be curious to hear more about your use case that you originally posted about to see if we can find an alternative if the above doesn't resolve it. For example, in the first example, what is GetMaxID doing? are you referencing the newly selectedRow anywhere?

Hi Tess,

I changed the script following your suggestion.
In the console log I now see: num = [object Object].
That's no what you expect I guess.

Regarding my original post: the GetMaxID is an SQL query to find the maximum of the existing ID's.
It has nothing to do with the selectRow and I removed the selectRow statement from the script.
At the moment your colleague Blake is investigating it.

kind regards
Reyer

Hi Reyer! Ah correction -- the console log would likely be console.log('num = '+ num[0]['COUNT(ID)']) to account for the nested data :slightly_smiling_face:\

Thanks for clarifying GetMaxID! Relying on a newly selected row would have some complexity, but since we don't need that here, we should be able to sort out a solution

After some attempts Blake from the Retool team found the solution.
This is the code that works:

// Assuming GetMaxLicenserID.trigger() returns a Promise
const maxResult = await GetMaxLicenserID.trigger();
const max = maxResult[0].Max_Id; // Assuming it returns an array

console.log('max = ' + max);

// Make sure max is a number and increment it by 1
if (!isNaN(max)) {
numberInputLicenserID.setValue(max + 1);
} else {
// Handle the case where max is not a valid number
console.error('Max ID is not a valid number');
}

Thanks a lot Blake for your great help!