Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Conditionable::when returns Collection when callback or default return empty value (e.g. 0) #40877

Closed
spaceemotion opened this issue Feb 8, 2022 · 13 comments · Fixed by #40888

Comments

@spaceemotion
Copy link

spaceemotion commented Feb 8, 2022

  • Laravel Version: 9.0
  • PHP Version: 8.1.2
  • Database Driver & Version: MySQL 8

Description:

I have the following snippet that calculates a number of serviced hours based on a condition:

$hours = $patient->serviceEntries->whenNotEmpty(
    static fn (Collection $entries) => $calculator->calcRegular($entries),
    static fn () => 0,
);

In case the calculator returns 0 hours (or the entries are empty) the expected result would be 0.
However, the function returns the collection itself, as the Conditionable trait returns $this when the return value is "empty":

if ($value) {
return $callback($this, $value) ?: $this;
} elseif ($default) {
return $default($this, $value) ?: $this;
}

The same logic applies to the unless function as well.

A possible solution is to use ?? instead of ?:. Not sure if this is a breaking change though (as it has worked before).

Steps To Reproduce:

$shouldBeZero = collect([1,2,3])->whenNotEmpty(fn () => 0, fn () => 0);
// returns the collection instance (with 1,2,3 as values)
@spaceemotion
Copy link
Author

I just tried the example out in Tinkerwell Web, it correctly returns 0 (as expected). Not sure which version of PHP and Laravel is bundled there, but my local tinker session has the following output:

$ php artisan tinker
Psy Shell v0.11.1 (PHP 8.1.2 — cli) by Justin Hileman
>>> collect([1,2,3])->whenNotEmpty(static fn () => 0, static fn () => 0)
=> Illuminate\Support\Collection {#4755
     all: [
       1,
       2,
       3,
     ],
   }

@driesvints
Copy link
Member

Seems like this is more of a feature request as this behavior is unchanged from 8.x? You mention: (as it has worked before). so was this different for you on 8.x?

@spaceemotion
Copy link
Author

Yes, this happened after the upgrade to v9 yesterday.

@driesvints
Copy link
Member

@inxilpro is this because of #37632 ?

@driesvints
Copy link
Member

@spaceemotion it's just odd to me because besides the changes from above PR it's the exact same code.

@spaceemotion
Copy link
Author

spaceemotion commented Feb 9, 2022

It seems like it is because of #37632.

The code in v8.x does not have the ?: $this appended:

https://github.com/laravel/framework/blob/8.x/src/Illuminate/Collections/Traits/EnumeratesValues.php#L478-L482

@driesvints
Copy link
Member

@spaceemotion you're correct! Can you send in a PR?

@spaceemotion
Copy link
Author

I can try this afternoon 👍

@spaceemotion spaceemotion changed the title Conditionable::when returns Collection when callback or default return empty value (e.g. 0) [9.x] Conditionable::when returns Collection when callback or default return empty value (e.g. 0) Feb 9, 2022
@inxilpro
Copy link
Contributor

inxilpro commented Feb 9, 2022

I think the reason I sent this PR to 9.x was because of this change. when() had very slightly different behavior across the framework, and that PR was meant to unify the behavior. I'll take a look a little later today to confirm.

@inxilpro
Copy link
Contributor

inxilpro commented Feb 9, 2022

Yeah, if you read #37632, I called this behavior out specifically. The reason for the change was to unify the behavior of when() across all implementations—some places used the ternary return and others didn't.

I agree with @spaceemotion that using the null coalesce operator would be preferable—I just used the ternary shorthand because that was what is used everywhere else in the framework.

@driesvints
Copy link
Member

Can one of you send in a PR?

@spaceemotion
Copy link
Author

@inxilpro Are you already working on this? If not, I could try it later.

@inxilpro
Copy link
Contributor

inxilpro commented Feb 9, 2022

Yeah, I can push up a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants