Power-Fx icon indicating copy to clipboard operation
Power-Fx copied to clipboard

Uninitialized record member not behaving as expected in Boolean context

Open daniel-schroeder-dev opened this issue 9 months ago • 0 comments

We're seeing some odd behavior in Power FX where a record member that hasn't yet taken on a value (so, it's Blank()) is not behaving as expected when we're using it in a Boolean context.

For example, we've got a conditional expression that returns true whenever both conditions are true (or truthy):

// gblSelectedPREntry is a record. has_guard is a 0 or 1, IsBlank() will be true or false
(gblSelectedPREntry.has_guard && IsBlank(gblSelectedPREntry.infopath_number))

When the app loads, the has_guard member of the gblSelectedPREntry has yet to be set, as it is set when a user clicks a checkbox. So, it returns Blank():

Image

The infopath_number is also Blank(), so the IsBlank() returns true:

Image

So, it would seem that this:

(gblSelectedPREntry.has_guard && IsBlank(gblSelectedPREntry.infopath_number))

Should equal this:

Blank() && true

But it doesn't!

Image

Our users figured out that if they toggle the checkbox where has_guard gets set to a 1 or 0, it starts behaving as expected.

So, before anything has been clicked, for some reason we're seeing true here instead of false:

Image

Once the has_guard box is clicked, we see true, which is what we would expect:

Image

If we uncheck has_guard, we see false, which is what we would have expected before checking the box, as well as after unchecking it:

Image

The issue started a few days ago. Looking at your commit history, this looks like it adjusted your Type system: https://github.com/microsoft/Power-Fx/commit/2403e3998c97640bd18f84fd0fc85d688e15db5c. Maybe that's the culprit? Or are we misunderstanding how the Type system is supposed to work in Power FX on our side?

We're going to file an issue with our internal Power Apps Microsoft representatives as well, but I figured I'd reach out here in the meantime. To mitigate the issue in the short term, casting to Boolean when a value may be Blank() seems to work.

// This __always__ works
(Boolean(gblSelectedPREntry.has_guard) && IsBlank(gblSelectedPREntry.infopath_number))

If that's the expected behavior, please close this issue!

daniel-schroeder-dev avatar Mar 13 '25 14:03 daniel-schroeder-dev