Livewire - Value will not be handed over to Filament Custom Form - pls explain

Hello Guys, we are trying to get NativePHP Camera Function working with Livewire and Filament V4 in a custom component Environment: Laravel: 12 Livewire: 3 Filament: 4 NativePHP: 1.13 The challange here is to get the data back to the Filament V4 Component from Livewire. What is working so far? The Camera event is working, and we can see the image displayed via "resources\views\livewire\camera.blade.php". We think the problem is with our Livewire Code, and NativePHP has no impact here ... So this means, NativePHP does it´s job so far. But we are not experienced with LiveWire - the current situation is, that the image data we expect from wire:model="{{ $getStatePath() }}" (resources\views\filament\forms\components\camera.blade.php) is not getting handed over to PHP / Filament. What we expect is, that the $state from Camera::make('string1') would contain the base64 image data, but in our code seems something wrong. The $state of this field seems to never get updated. Could someone please explain what´s wrong here? At the moment, we have absolutely no clue, what´s missing here. many thanks BR Files: i try to upload as comment...
4 Replies
nighty
nightyOP3w ago
app\Filament\Resources\featuretests\Schemas\featuretestForm.php
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name'),
Camera::make('string1'),
]);
}
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name'),
Camera::make('string1'),
]);
}
app\Filament\Forms\Components\Camera.php
<?php

namespace App\Filament\Forms\Components;

use Filament\Forms\Components\Field;

class Camera extends Field
{
protected string $view = 'filament.forms.components.camera';
}
<?php

namespace App\Filament\Forms\Components;

use Filament\Forms\Components\Field;

class Camera extends Field
{
protected string $view = 'filament.forms.components.camera';
}
resources\views\filament\forms\components\camera.blade.php
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div
x-data="{ state: $wire.$entangle(@js($getStatePath())) }"
{{ $getExtraAttributeBag() }}
>
<livewire:camera
wire:model="{{ $getStatePath() }}"
:wire:key="$getId().'-'.$getStatePath()"
/>
</div>
<div>{{ $getStatePath() }}</div>
</x-dynamic-component>
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div
x-data="{ state: $wire.$entangle(@js($getStatePath())) }"
{{ $getExtraAttributeBag() }}
>
<livewire:camera
wire:model="{{ $getStatePath() }}"
:wire:key="$getId().'-'.$getStatePath()"
/>
</div>
<div>{{ $getStatePath() }}</div>
</x-dynamic-component>
app\Livewire\Camera.php
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Log;
use Livewire\Attributes\On;
use Livewire\Component;
use Native\Mobile\Events\Camera\PhotoTaken;
use Native\Mobile\Facades\Camera as CameraFacade;

class Camera extends Component
{
public $state;

public function camera()
{
Log::debug("Get Photo");
CameraFacade::getPhoto();
}

//this is never triggered, we do not understand why ...
public function updatedState($value)
{
Log::debug("Updated state to: {$value}");
}

#[On('native:'.PhotoTaken::class)]
public function handle(string $path)
{
$data = base64_encode(file_get_contents($path));
$mime = mime_content_type($path);

$this->state = "data:$mime;base64,$data";
Log::debug("Handled Photo: ".strlen($this->state));
}

public function render()
{
return view('livewire.camera');
}
}
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Log;
use Livewire\Attributes\On;
use Livewire\Component;
use Native\Mobile\Events\Camera\PhotoTaken;
use Native\Mobile\Facades\Camera as CameraFacade;

class Camera extends Component
{
public $state;

public function camera()
{
Log::debug("Get Photo");
CameraFacade::getPhoto();
}

//this is never triggered, we do not understand why ...
public function updatedState($value)
{
Log::debug("Updated state to: {$value}");
}

#[On('native:'.PhotoTaken::class)]
public function handle(string $path)
{
$data = base64_encode(file_get_contents($path));
$mime = mime_content_type($path);

$this->state = "data:$mime;base64,$data";
Log::debug("Handled Photo: ".strlen($this->state));
}

public function render()
{
return view('livewire.camera');
}
}
resources\views\livewire\camera.blade.php
<div class="space-y-6">
<x-filament::button wire:click="camera">
Take a Photo
</x-filament::button>

@if ($state)
<img src="{{ $state }}" class="rounded-xl shadow max-w-sm w-full h-auto mt-12 mx-auto" />
@endif
</div>
<div class="space-y-6">
<x-filament::button wire:click="camera">
Take a Photo
</x-filament::button>

@if ($state)
<img src="{{ $state }}" class="rounded-xl shadow max-w-sm w-full h-auto mt-12 mx-auto" />
@endif
</div>
toeknee
toeknee3w ago
Would that not be the same as this field? https://filamentphp.com/plugins/emmanpbarrameda-take-picture-field Which will allow you to review how he handled it?
Filament
Take Picture Field by Emman Barrameda - Filament
A custom Filament form component to capture photos from your device camera.
nighty
nightyOP3w ago
the solution was to change Camera.php to this, and add #[Modelable] - tbh, i do not fully understand, but it´s working as expected now, here the updated file, to save someone else 2-3 days 🙂
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Log;
use Livewire\Attributes\On;
use Livewire\Component;
use Native\Mobile\Events\Camera\PhotoTaken;
use Native\Mobile\Facades\Camera as CameraFacade;
use Livewire\Attributes\Modelable;

class Camera extends Component
{
#[Modelable]
public $state;

public function camera()
{
Log::debug("Get Photo");
CameraFacade::getPhoto();
}

public function updatedState($value)
{
Log::debug("Updated state to: {$value}");
}

#[On('native:'.PhotoTaken::class)]
public function handle(string $path)
{
$data = base64_encode(file_get_contents($path));
$mime = mime_content_type($path);

$this->state = "data:$mime;base64,$data";
Log::debug("Handled Photo: ".strlen($this->state));
}

public function render()
{
return view('livewire.camera');
}
}
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Log;
use Livewire\Attributes\On;
use Livewire\Component;
use Native\Mobile\Events\Camera\PhotoTaken;
use Native\Mobile\Facades\Camera as CameraFacade;
use Livewire\Attributes\Modelable;

class Camera extends Component
{
#[Modelable]
public $state;

public function camera()
{
Log::debug("Get Photo");
CameraFacade::getPhoto();
}

public function updatedState($value)
{
Log::debug("Updated state to: {$value}");
}

#[On('native:'.PhotoTaken::class)]
public function handle(string $path)
{
$data = base64_encode(file_get_contents($path));
$mime = mime_content_type($path);

$this->state = "data:$mime;base64,$data";
Log::debug("Handled Photo: ".strlen($this->state));
}

public function render()
{
return view('livewire.camera');
}
}
ok seems there are more things to consider - with this variant only one upload per page is possible .... we need to figure out what causes the problm.
toeknee
toeknee3w ago
Change state to be and arrary and merge them?

Did you find this page helpful?