dr_ermio
dr_ermio

Reputation: 851

Laravel Conditional API Resource executing all functions even if unnecessary?

So I have a Laravel API Resource that returns standard database information for a model. However, in some instances, I need this resource to present some data that triggers a complex/slow query.

When I need this data, I do not mind having it take longer, but since most use cases will not needed it, I thought to present it conditionally using the $this->when() method in the resource.

class SomeResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'created_at' => $this->created_at,

            //The "slow_query()" should not be executed
            'slow_result' =>  $this->when(false, $this->slow_query()),
        ];
    }
}

For my surprise, even when the when condition is false, the slow query is still executed, even though the result is never shown and the query is useless.

How can I prevent the slow_query() method from running when it is not needed?

This is on Laravel 5.8

Upvotes: 0

Views: 713

Answers (1)

mdexp
mdexp

Reputation: 3567

When you call a php function, you have to compute the values of the arguments you are passing to it before the actual execution of the function. That's why you always execute that slow_query() method all the times, also when the condition is false.

A solution might be to wrap that function call in a closure:

class SomeResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'created_at' => $this->created_at,

            //The "slow_query()" should not be executed
            'slow_result' => $this->when(false, function () {
                return $this->slow_query();
            }),
        ];
    }
}

In this way when the condition is true, your closure will gets triggered and therefore the query executed and its return value returned by the ->when(...) function call

Upvotes: 7

Related Questions