Mvc plugin flashmessager not work with render() nothing

I built my flashmessager function in the following steps

  1. run composer command( and choose to inject configuration in modules.config.php):
composer require laminas/laminas-mvc-plugin-flashmessenger
  1. add message in an action like :frowning:
    public function qqcallbackAction()
    {
        $request = $this->getRequest();
        $identityArr = $this->plugin('auth')->getIdentity($request);
        if ($identityArr) return $this->redirect()->toRoute('user', ['action' => 'profile']);

        $response = $this->getResponse();

        /** @var MembersPlugin $membersPlugin */
        $membersPlugin = $this->plugin('members');
        $errMsg = $membersPlugin->qqcallback($request, $response);
        if ($errMsg)
        {
            $this->flashMessenger()->addSuccessMessage('紫霞喊你'); //addSuccessMessage or addErrorMessage both not work.
            return $this->redirect()->toRoute('user', ['action' => 'thirdguide']);
        }
        return $this->redirect()->toRoute('user', ['action' => 'profile']);
    }
  1. render the message in the view script of another action(thirdguide.phtml):
<!--99999999999999999999999999-->
<?= $this->flashMessenger()->render('success'); //success or error both nothing show ?>
<!--99999999999999999999999999-->

but !!!
if i place the message render inside the action its own view script, it works!!
that means when I place the clothest above code inside qqcallback.phtml, you know it is the same action which I add the message there.

I strictly following the official document Basic Usage - laminas-mvc-plugin-flashmessenger - Laminas Docs

It is session based, so I pasted my session configuration here for reference (in global.php).

retrun [
    // other configuration like db here
    'session_containers' => [
        Laminas\Session\Container::class,
    ],

    'session_config' => [
        'cache_expire' => 86400 * 30,
        'cookie_httponly' => true,
        'cookie_lifetime' => 86400 * 30,
        'gc_maxlifetime' => 86400 * 30,
        'name' => 'llren',
        'remember_me_seconds' => 86400 * 30,
        'use_cookies' => true,
    ],

    'session_storage' => [
        'type' => Laminas\Session\Storage\SessionArrayStorage::class,
    ],

    'session_manager' => [
        'validators' => [
            Laminas\Session\Validator\RemoteAddr::class,
            Laminas\Session\Validator\HttpUserAgent::class,
        ],
    ],
];

any body can help me out? So appreciated! I have been working on that for a whole afternoon.

I found that It works between actions redirect only when they don’t have viewModel.

A action addMessage, A don’t return viewmodel.

public function thirdguideAction()
    {
        $request = $this->getRequest();
        $identityArr = $this->plugin('auth')->getIdentity($request);
        if ($identityArr) return $this->redirect()->toRoute('user', ['action' => 'profile']);

        $this->flashMessenger()->addErrorMessage('紫霞喊你');

        /*if ($this->flashMessenger()->hasErrorMessages()) {
            print_r($this->flashMessenger()->getErrorMessages());
        }*/
        exit;

        $vm = new ViewModel();
        return $vm;
    }

B action

public function thirdlocaluiAction() : ViewModel
    {
        if ($this->flashMessenger()->hasErrorMessages()) {
            print_r($this->flashMessenger()->getErrorMessages());
        }
        exit;

        $vm = new ViewModel();
        return $vm;
    }

It works at no returning view model.
When A return view model.
B can not get the message at all.

Why, why, why, I gonna crazy.

I got a conclusion that.

  1. the action which add a flash message can not return a view model.
  2. the actions which involved in the flash messager can not inject the dependency of the SessionContainer.

If it inject the Session Conatiner as the dependency in the controller __construct() fucntion. it won’t work well as expected.

I think you are mixing things up here, because there are messages from the previous request and from the current one. See the methods of the plugin:

Why not?

Hi @jobsfan,
Your assumption is a rookie mistake. Flash messages tend to be used after performing an action successfully.

If you want to show something right after doing something then why use flash messenger at all use your own ViewModel property and pass it to the ViewModel, like when setting an error message or showing error messages of forms. Session values are used to send data after a request is completed and used on a request which is unaware of its predecessor. So, what is the use of session variables if you use them in the same request and dispose of them? Thanks!

Thanks for your reply!

I wanna to bring message from one action to another, however I encountered problem, it did not perform as expected.

So I wanna to figure out what’s the problem.
Pass massage from action to its own view is a test, not I pretent to do at the first.

I want to find where the problem is.

I don’t know why there return the viewModel from the previous action then the message gone.
As well I don’t know why the receipt action if there is a SessionContainer inject in the contruct fucntion of the controller, the message also disapeared. I totally confused.

Unfortunately, confusion always arises here, because in fact this is about passing messages from one request to the next request.

Based on the skeleton application and the description from the documentation for the controller plugin and session, everything works as expected.

Short example:

namespace Application\Controller;

use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger;
use Laminas\Session\Container as SessionContainer;

/**
 * @method FlashMessenger flashMessenger()
 */
final class ExampleController extends AbstractActionController
{
    public function __construct(
        private readonly SessionContainer $sessionContainer
    ) {
    }

    public function firstAction()
    {
        $this->flashMessenger()->addSuccessMessage('Success!');
        $this->flashMessenger()->addErrorMessage('Error!');

        $this->sessionContainer->test = 'Hello world!';

        return $this->redirect()->toRoute('second');
    }

    public function secondAction()
    {
        var_dump($this->flashMessenger()->hasSuccessMessages()); // true
        var_dump($this->flashMessenger()->hasErrorMessages()); // true
        var_dump($this->flashMessenger()->getSuccessMessages()[0]); // Success!
        var_dump($this->flashMessenger()->getErrorMessages()[0]); // Error!

        var_dump($this->sessionContainer->test ?? null); // Hello world!

        return [];
    }
}

Also the message of the current request:

public function thirdAction(): array
{
    $this->flashMessenger()->addSuccessMessage('Success!');

    var_dump($this->flashMessenger()->hasCurrentSuccessMessages()); // true
    var_dump($this->flashMessenger()->getCurrentSuccessMessages()[0]); // Success!

    return [];
}

So please check the messages like above or use a debugger to check if something is written to the global $_SESSION variable.

And caution with the general methods of the plugin because the following means that the default namespace will be used:

public function thirdAction(): array
{
    $this->flashMessenger()->addSuccessMessage('Success!');

    var_dump($this->flashMessenger()->hasCurrentMessages()); // false
    var_dump($this->flashMessenger()->getCurrentMessages()); // []

    return [];
}

This works:

var_dump($this->flashMessenger()->hasCurrentMessages(
    $this->flashMessenger()::NAMESPACE_SUCCESS
)); // true
var_dump($this->flashMessenger()->getCurrentMessages(
    $this->flashMessenger()::NAMESPACE_SUCCESS
)[0]); // Success!

// OR

var_dump($this->flashMessenger()->hasCurrentMessages('success')); // true
var_dump($this->flashMessenger()->getCurrentMessages('success')[0]); // Success!

But with the auto-completion of your IDE it is much simpler:

var_dump($this->flashMessenger()->hasCurrentSuccessMessages()); // true
var_dump($this->flashMessenger()->getCurrentSuccessMessages()[0]); // Success!
1 Like

I have been temporarily cross over the step by removed my DI of session container in my controller 's construction.

Because my project have to move on.

If I have time in the future, I will try to figure out why I can not add the session container as DI in this situation.

Thank you so much for helping.

Hi @jobsfan,

According to your below message, your usage of flashMessage is not ideal in this situation. Because as the name suggests it is to be used as a flash message and it does what the name suggests. Which is to show the message after a successful request and remove it right afterwards. I would suggest using a session container using session in your controller through reflection-based configuration as described here. Thanks!