nova-issues icon indicating copy to clipboard operation
nova-issues copied to clipboard

storeAs in a Repeater field

Open Brand3000 opened this issue 1 year ago • 7 comments

Hi! Tho storeAs feature doesn't work in Repeaters. Is it difficult to fix it? Very inconvenient.

Brand3000 avatar Aug 29 '24 11:08 Brand3000

Hi @Brand3000, thanks for reporting this. To help investigating, please post an example to illustrate the case and ease the reproduction 🙏

jeremynikolic avatar Sep 01 '24 19:09 jeremynikolic

It's very easy to reproduce. Just try using the storeAs function on any image field in a repeatable class.

Brand3000 avatar Sep 02 '24 11:09 Brand3000

I am unfortunately not able to reproduce the issue. Setting up a Repeater with an item containing a file or image field, and using storeAs callback, behave as expected.

Please provide further information of the context leading to the issue you encounter so we may assist.

jeremynikolic avatar Sep 02 '24 13:09 jeremynikolic

There's my field declaration:

Image::make('Image 1 (330 x 220)', 'image1')->storeAs(function (Request $request) {
                return pathinfo($request->image1->getClientOriginalName(), PATHINFO_FILENAME).'_'.uniqid().'.'.pathinfo($request->image1->getClientOriginalName(), PATHINFO_EXTENSION);
            })->disk('public_tour')->prunable()->hideFromIndex(),

and there's the error: App\Nova\Repeater\ScheduleItem::App\Nova\Repeater\{closure}(): Argument #1 ($request) must be of type App\Nova\Repeater\Request, Laravel\Nova\Http\Requests\UpdateResourceRequest given. It works fine if I remove the storeAs method from the chain.

The same field with the same settings works perfect in the parent resource.

Brand3000 avatar Sep 03 '24 06:09 Brand3000

Thanks for the details 👍

It's missing the right import as per the exception indicates. You'd need importing \Illuminate\Http\Request ~~or \Laravel\Nova\Http\Requests\NovaRequest if you need something more specific (and adjust Request to NovaRequest accordingly)~~ 🤔

jeremynikolic avatar Sep 03 '24 08:09 jeremynikolic

Unfortunately, the NovaRequest class doesn't have the getClientOriginalName method as it's written in the docs. My code is:

use Laravel\Nova\Http\Requests\NovaRequest;

            Image::make('Image 1 (330 x 220)', 'image1')->storeAs(function (NovaRequest $request) {
                return pathinfo($request->image1->getClientOriginalName(), PATHINFO_FILENAME).'_'.uniqid().'.'.pathinfo($request->image1->getClientOriginalName(), PATHINFO_EXTENSION);
            })->disk('public_tour')->prunable()->hideFromIndex(),

Brand3000 avatar Sep 03 '24 08:09 Brand3000

As you are in a repeater, your file is nested within the resource payload.

$request->file("{resource_key}.{repeater_iteration}.fields.image1")

With that said, I realized while looking into this that you'll be missing a way to know which file is the one (which repeater_iteration pretty much) for which the storeAs was called for, due to it being in a repeater. In other methods we inject a requestAttribute parameter which will tell you which one it is. I'll take note of that specific case and see for us to address 👍

jeremynikolic avatar Sep 03 '24 09:09 jeremynikolic

Released with Laravel Nova 5.0.0

Feel free to open up a new issue if you're still experiencing this problem on the latest version.

crynobone avatar Dec 16 '24 04:12 crynobone