Home > Software engineering >  Return Laravel options() as array when no optional parameter has been provided
Return Laravel options() as array when no optional parameter has been provided

Time:12-24

Laravel has the super handy optional() helper.

I would like to combine it with a custom Model attribute like this:

// this method is on the User model
public function getDataAttribute()
{
    // this data comes from another service
    $data = [
        'one' => 1,
        'two' => 2,
    ];

    return optional($data);
}

So I can use it like this:

$user->data->one // 1
$user->data->two // 2
$user->data->three // null

However, I am also trying to return the entire array by doing:

dump($user->data); // this should dump the internal $data array

But this will return an instance of Illuminate\Support\Optional with a value property.

Illuminate\Support\Optional {#1416 ▼
  #value: {#2410 ▼
     "one": 1
     "two": 2
  }
}

Is it possible to return the original $data array if no "sub"parameter (= a child attribute of $user->data) is given? Or is there a possibility to detect a child parameter in the getDataAttribute()?

I hope it's clear what I am trying to achieve.

CodePudding user response:

What you're asking for cannot be achieved.

My suggestion would be to keep things simple and define a getter method and pass the key of the array you want and from there return your data respectively, e.g.:

public function getData($key = null) {
    $data = [
        'one' => 1,
        'two' => 2,
    ];

    if (!$key) {
        return $data;
    }

    return $data[$key] ?? null;
}

Notice also how this method is no longer an attribute, this is because AFAIR, you cannot pass args to attribute methods.

Reading Material

Null coalescing operator

CodePudding user response:

Thanks to lagbox for pushing me in the right direction. I have solved this by using the following macro:

Illuminate\Support\Optional::macro('toArray', function()
{
    return (array) $this->value;
});

This way I can access all data by using:

$user->data->toArray();
  • Related