Issue
I have an array in Laravel applications that I would like to modify in Laravel listener. PHP by default passes an array by value however, the way Laravel events and its listeners work I am unable to modify the original variable. Is there a better way than what I am doing below?
The Model where the event is fired from.
Model: Event.php
namespace Vendor\Package\Models
use Vendor\Package\Events\PageNodeArrayAfter;
use Event;
class Page
{
public function toArray()
{
$data = [];
// do something with the data.
Event::fire(new PageNodeToArrayAfter($data))
// The data should be modified by a listener when I use it here.
}
}
Event: PageNodeToArrayAfter.php
namespace Vendor\Package\Events;
class PageNodeToArrayAfter
{
/**
* Props to be sent to the view
* @var array $data
*/
protected $data = [];
/**
* @param array $data
*
*/
public function __construct(array &$data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
}
Listener: FlashMessagesListner.php
namespace Vendor\Package\Listeners;
class FlashMessagesListner
{
protected $data = [];
public function handle(PageNodeToArrayAfter $event)
{
$this->data = $event->getData();
// The problem here is the $data is no logner a reference here.
}
}
Solution
I appreciate all the responses, feedback on the question and suggestions to look for a better way of doing it.
Now instead of using Listeners, I tried Laravel Pipeline which is a great way of passing the data through different pipes and in my case filtering it. This article has been very helpful in understanding it https://jeffochoa.me/understanding-laravel-pipelines
Here is the final version of my code and how am I using Laravel Pipeline:
Node: Page.php
<?php declare(strict_types=1);
namespace Vendor\Package\Nodes;
class Page extends ReactPage
{
public function toArray() : array
{
$data = parent::toArray();
$pipes = [
AppendFlashMessage::class,
RemoveEmptyLayoutNode::class
];
// Filter data through the pipelines.
$data = app(Pipeline::class)
->send($data)
->through($pipes)
->via('filter')
->then(function($data) {
return $data;
});
return $data;
}
}
Pipe: AppendFlashMessage.php
<?php declare(strict_types=1);
namespace Vendor\Package\Pipeline;
use Closure;
class AppendFlashMessage
{
public function filter(array $data, Closure $next) : array
{
// step 1: pull the errors from session.
$errors = [
'type' => 'error',
'message' => 'Invalid User Name'
];
$data['messages'] = $errors;
return $next($data);
}
}
Answered By - Aftab Naveed
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.