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

Livewire - unable to call lazy data #257

Closed
francoism90 opened this issue Nov 18, 2022 · 7 comments
Closed

Livewire - unable to call lazy data #257

francoism90 opened this issue Nov 18, 2022 · 7 comments

Comments

@francoism90
Copy link
Contributor

francoism90 commented Nov 18, 2022

$this->findUserOrFail(1)
    ->getData() // I'm using the data trait
    ->include(
           'name',
           'email',
    );

It doesn't seem the include is being parsed/loaded.

Result:

htmlspecialchars(): Argument #1 ($string) must be of type string, Spatie\LaravelData\Support\Lazy\DefaultLazy given

My blade simple uses: {{ $user->email }}

If more info is needed, please let me know!

Thanks

@francoism90
Copy link
Contributor Author

This works:

$user->email->resolve()

However I don't think this is correct?

Maybe a loader for Livewire should be added: https://github.com/spatie/laravel-data/blob/main/docs/advanced-usage/use-with-inertia.md

@rubenvanassche
Copy link
Member

rubenvanassche commented Nov 18, 2022

Hi @francoism90,

This is correct behavior, calling include on a property will only affect when you're transforming a data class (toArray, toResponse, toJson, ....).

Inertia works a bit different then LiveWire since it will internally call toArray on the data object, that's a possible solution to this problem but you'll lose typing within your views.

Another solution could be to make lazy HtmlAble and then render the content, and also catch any property fetch or method on the lazyily incuded variable. In such case we could resolve the lazy object and pass on the call. This is a lot of magic, at this point I'm not certain if we want such a thing. But you could always implement it yourself by extending Lazy within your project.

@francoism90
Copy link
Contributor Author

francoism90 commented Nov 18, 2022

@rubenvanassche Thanks for your reply! I don't fully understand the HtmlAble, but I'll look into it.

Would you recommend to use $user->email->resolve() as an alternative?

I didn't test <input type="text" wire:model="user.email" />, does this work fine on lazy attributes?

Thanks!

@rubenvanassche
Copy link
Member

Would you recommend to use $user->email->resolve() as an alternative?

Yeah!

I didn't test , does this work fine on lazy attributes?

I would expect not, since the lazy prop will be used.

@francoism90
Copy link
Contributor Author

@rubenvanassche Sorry for bumping this, but could you please tell me how it should work with Htmlable?

I've found this post: https://itnext.io/laravel-the-fantastic-4-interfaces-renderable-6dbdd3c5e539

If I understand correctly, I need to check if the property is a Lazy instance and use resolve(), or when it's already resolved, return without this method.

This is what I'm doing now:

return $data->somelazy instanceof Lazy ? $data->somelazy->resolve() : $data->somelazy;

@rubenvanassche
Copy link
Member

I would create a new Lazy class underneath the package Lazy class, extend HtmlAble which has a render method if I'm not mistaken and then use the code you've provided above.

Then in your data classes you would use your own implemented Lazy class instead of the default laravel-data one.

@francoism90
Copy link
Contributor Author

@rubenvanassche Thanks for your input! I'll try to extend the Lazy class with HtmlAble and see how this works out for us. :)

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

No branches or pull requests

2 participants