I have 2 Components, the parent one is Listing\Create and the child one is ImageUpload. They communicate with each other using Events. The problem is, there is no way to indicate that I want the event to finish before continuing, and since they work asynchronously, I need a way to indicate that they need to be waited on. I've been at it for hours, so maybe I need to rethink the whole logic, but I've found this way to be the most cleanest and easiest for me.
Summarized Listing\Create:
class Create extends Component
{
public $isImageValidated = false;
#[On('validate-image-fields')]
public function isImageValidated($isVerified)
{
$this->isImageValidated = $isVerified;
\Debugbar::addMessage($this->isImageValidated, 'listing-var');
}
public function save()
{
\Debugbar::addMessage('Saving Listing', 'listing1');
$this->dispatch('validate-image')->to(ImageUpload::class); //1st event
$this->validate();
\Debugbar::addMessage($this->isImageValidated, 'listing2');
if($this->isImageValidated) { //This variable can only be changed through the isImageValidated(boolean) function
...
Then there is the child component:
class ImageUpload extends Component
{
public $isVerified = false;
protected function rules()
{
return [
'image' => 'nullable|image|mimes:jpg,jpeg,bmp,png,webp|max:2048',
'alt' => 'nullable|string|max:200',
];
}
#[On('validate-image')]
public function updatedImage(): void
{
\Debugbar::addMessage('Validating image...', 'validate1');
$rules = $this->rules();
$validator = Validator::make([
'image' => $this->image,
'alt' => $this->alt,
], $rules);
if($validator->fails()) {
$this->removeImage(); //Function that handles the removing of the image preview
$this->isVerified = false;
} else {
$this->isVerified = true;
}
\Debugbar::addMessage($this->isVerified, 'validate2');
$this->dispatch('validate-image-fields', isVerified: $this->isVerified)->to(Create::class); //2nd event
}
The output from Debugbar is:
update#3 (ajax):
Saving Listing[listing1]
false[listing2] //Here's the problem, it doesnt wait for the event in the child component to complete and set the $this->isImageValidated, so it stays false.
--------------------
update#4 (ajax):
Validating image....[validate1]
true[validate2]
--------------------
#5 update(ajax):
true[listing-var]
I understand why it's not working. It first executes the whole save() code, and it doesnt wait for the validate-image event to complete. The Livewire documentation doesn't address this, nor does it mention that the events are asynchronous, which led me to writing the code the way I did. I figured it doesn't continue, until the event function is fully completed, because that makes more sense, but oh well. What are the workarounds and the best practices for this?