One time update with Now(0) Not working as intended

Hello, I have a rather small problem but all the same it still bothers me it won’t work. I have a text field that I want to update the current time until someone hits a button to “capture” the data (other fields as well, but they are irrelevant).

At that time when they hit the button I figure that I can have a Boolean tell my text value to stop updating/polling and stop where it was and display the moment the button was pressed.

this is what’s on the text value to display:

if({this.custom.timeTrack},
now(1000),
now(0)
)

If the Boolean is on, it should auto poll and display the ongoing time, if not, then it should poll once and then stop where it was. What happens is one of two things depending on if I am in the designer or looking at it from a perspective page:

Designer: the value continues to poll as if the Boolean didn’t change at all.

Perspective Page: The value updates to the time when the now() originally ran when the page was updated. It does not poll again unless the page reloads.

I’m sure the answer is simple, but any help… helps! Thanks! :slight_smile:

Create a custom property on the view called stopTs or similar. When your button is pressed, write the current timestamp to the custom property. When you want to display live time again, write None to the property.

Your label's binding would then turn into

if(
	isNull({self.view.custom.stopTs}), 
	now(1000), 
	{self.view.custom.stopTs}
)
2 Likes

If you tied it to a tag instead of custom view property, you could do this:

if({tag},
	now(1000),
	{tag.timestamp}
)
3 Likes

That breaks down once you have multiple people in the interface at once.

2 Likes

You could use coalesce to express this a little more concisely (possibly less readably, your mileage may vary):
coalesce({self.view.custom.stopTs}, now(1000))


I don't actually know if this would work, but you could also try:

now(if({this.custom.timeTrack}, 1000, 0))
5 Likes

A polling now() anywhere in an expression will cause it to poll after it executes even once. Short-circuiting in if() or other conditionals won't stop it.

You can make the poll interval itself an expression.

3 Likes

Oh I have similar code!
now(x*1000) as expression binding.
in this case, set the x. your script transform code will now run accordingly. if x is 0, it wont.

I called this feature refresh rate.

1 Like

If you want to be better understood by others, consider calling it the poll rate, as that is what IA calls that value.

Be aware that changing "x" to zero will itself trigger one last execution.

3 Likes

Sorry all for the late response! This was the solution :grinning_face_with_smiling_eyes: .

I think having two separate Now()s makes ignition confused and want to execute both even though the one logic path is false? Basically what Phil said is what’s happening.

Regardless, like I said the solution was probably simple and this solved my problem. Thank you!

It's not confused. That's just how polling in now() and runScript() have always worked.

1 Like

'Confused' is reasonable, in my opinion, as you've uncovered the ambiguity in outcomes when mixing multiple polling functions with event-based.
Specifically,
if(true, now(1000), now(0)) // timestamp updates every second
but,
if(false, now(1000), now(0)) // timestamp never updates after initial

Replacing, true/false in the expressions above with a custom bool property (as in the original post) causes the expression to act as-expected on the initial binding... things fall apart when toggling the bool prop. In my testing (8.1.42) with:
if({this.custom.bool}, now(1000), now(0))

  1. Initial update (bool = false), timestamp never updates.
  2. First Toggle (bool = true), timestamp updates every second.
  3. Second Toggle (bool = false), timestamp updates every second.

That outcome is cause for :thinking:, certainly not intuitively obvious to a casual observer.
Changing the expression to the marked solution with variable time now(f(x)) produces reliable outcomes. :+1:

1 Like

Polling is established by execution, and causes the entire expression to re-execute at a later time, and thereafter, until an execution causes the poll interval to change.

Note that when now() and runScript() were introduced (long ago), if() and other boolean expressions did not short-circuit as they do now. Polling expression functions are not strictly compatible with short-circuiting, and never have been.

1 Like