I have an Laravel application for Properties, let's say somewhere in my code I do:
$property = new Property();
$property->city = "New York";
...
$property->save();
Then I have Event Listener that listens for specific event:
$events->listen(
'eloquent.saved: Properties\\Models\\Property',
'Google\Listeners\SetGeoLocationInfo@fire'
);
And finally in SetGeoLocationInfo.php I have
public function fire($event)
{
$property = $event;
...
//get GPS data from Google Maps
$property->latitude = $googleMapsObject->latitude;
$property->longitude = $googleMapsObject->longitude;
$property->save();
}
And when I save model in goes to infinite recursion, because of save() evoked in the handler.
How I can change my code to make it fill location data just one time after saving and avoid recursion?
I cannot use flushEventListeners() because in this case other listeners stop working (e.g. property photo attaching).
in my case using saveQuietly() instead of save() resolved the issue as the saveQuietly does not trigger any events so you are not stuck in an infinite loop of events.
edit: i think the saveQuietly() method is only available in laravel 8 for now.
I hit the same. In Laravel 5.6 you can simply override the finishSave() function in your model:
protected function finishSave(array $options)
{
// this condition allow to control whenever fire the vent or not
if (!isset($options['nosavedevent']) or empty($options['nosavedevent'])) {
$this->fireModelEvent('saved', false);
}
if ($this->isDirty() && ($options['touch'] ?? true)) {
$this->touchOwners();
}
$this->syncOriginal();
}
Then you can use it like this:
public function fire($event)
{
$property = $event;
...
//get GPS data from Google Maps
$property->latitude = $googleMapsObject->latitude;
$property->longitude = $googleMapsObject->longitude;
$property->save(['nosavedevent' => true]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With