I have solved it with two intermediaries:
Livewire component includes a blade component:
<form wire:submit.prevent="createAddress">
<div class="form-group" >
<x:google-address-lookup wire:model.lazy="lookup" />
</div>
<div class="form-group">
<button
type="submit"
class="btn btn-outline-secondary"
wire:submit.prevent="createAddress">{{__('Add Address')}}</button>
</div>
</form>
A Blade component
<div class="input-group"
wire:ignore
x-data={lookup:{}}
x-init="() => {
new AddressAutocomplete('.google-address-lookup', (result, raw) => {
@this.set('lookup', result)
});
}"
{{ $attributes }}
>
<input
x-data
x-on:address:list:refresh.window="$('.google-address-lookup').val('')"
x-on:keydown.enter.prevent
wire:ignore.self
wire:loading.attr="readonly"
autocomplete="google-lookup"
class="form-control google-address-lookup"
required
type="search"
>
</div>
So that the livewire model “lookup” is wrapping the input manipulated by Google PAC
This way the input value is a string and out $address
model is an array, as needed.
I expect that the user may want to enter multiple addresses, one after the other, so i clear the input (hence the events)
Now, in Livewire component class, cleaned up for brevity
namespace App\Http\Livewire\Customer\Address;
use App\Actions\Customer\CreateGoogleAddress;
use App\Codices\Customer\NewGoogleAddressCodex;
use App\Models\Customer;
use Livewire\Component;
class Create extends Component
{
/**
* Bind the Model
*
* @var App\Models\Customer
*/
public $customer;
/**
* Lookup intermediary
*
* @var
*/
public $lookup;
/**
* Address
*
* @var array
*/
public $address = [];
/**
* Mount component
*
* @param App\Models\Customer $customer
* @return void
*/
public function mount(Customer $customer)
{
$this->customer = $customer;
}
/**
* Render the component
*
* @return Illuminate\View\View
*/
public function render()
{
return view('livewire.customer.address.create');
}
/**
* Listen to updating event
* Push the value of lookup into the $address
*
* @param string $field
* @param mixed $value
* @return void
*/
public function updating($field, $value)
{
if ($field == 'lookup' and is_array($value)) {
$this->address = $value;
}
}
/**
* Listen to updated event
*
* @param string $field
* @return array
*/
public function updated($field)
{
$this->validateOnly($field, [
'address.cityName' => 'required|string',
'address.country' => 'required|string',
'address.state' => 'required|string',
'address.streetName' => 'required|string',
'address.streetNumber' => 'nullable|string',
'address.zipCode' => 'required|string',
]);
}
/**
* Create customer address
*
* @return
*/
public function createAddress()
{
$this->customer->addresses()->create($this->address);
$this->dispatchBrowserEvent('address:list:refresh');
}
}
I do not get the feeling that it is overly hacky; what do you think, @calebporzio ?