Flash message not showing up in twig templates

I have the below dependency injection configured.

I am using Version 6 | Session (odan.github.io) for the session management and flash messages.

$containerBuilder->addDefinitions([
    Twig::class => function (ContainerInterface $c): Twig {
        $twig = Twig::create($path, [
            'cache' => CHUM_CACHE_PATH,
            'autoescape' => false,
            'debug' => true
        ]);

        $flash = $c->get(SessionInterface::class)->getFlash();
        $twig->getEnvironment()->addGlobal('flash', $flash);

        return $twig;
    },
    SessionManagerInterface::class => function (ContainerInterface $c): SessionInterface {
        return $c->get(SessionInterface::class);
    },
    SessionInterface::class => function (ContainerInterface $c) {
        $options = [
            'name' => 'app',
            'lifetime' => 7200,
            'path' => null,
            'domain' => null,
            'secure' => false,
            'httponly' => true,
            'cache_limiter' => 'nocache',
        ];

        return new PhpSession($options);
    },
]);

$app->add(SessionStartMiddleware::class);

I am setting the error message when there is a form validation issue and redirect the page to the same url again to show the message.

class InstallController extends BaseController
{
    public function index(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
         $form = $this->createForm(InstallAppConfigType::class);

        $req = Request::createFromGlobals();

        $this->session->getFlash()->set("error", array("Invalid Root Path"));

        $form->handleRequest($req);

        if ($form->isSubmitted() && $form->isValid()) {
            $app = $form->getData();

            if (!is_dir($app->getRootPath())) {
               // SETTING FLASH MESSAGE IN CASE OF ANY VALIDATION ISSUE
                $this->session->getFlash()->set("error", array("Invalid Root Path", "Check Permissions"));
                return $this->redirectByName($response, "install"); // redirect to same page to show error
            }

            return $this->redirectByName($response, "install.db");
        }

        return $this->render(
            $request,
            $response,
            'install.start.twig',
            array('form' => $form->createView())
        );
    }
}

Below is the twig template.

      <span>Test : {{ flash.get('error') | first }}</span>

      {% for message in flash.get('error') %}
      <div class="alert alert-error shadow-lg">
        <span>{{ message }}</span>
      </div>
      {% endfor %}

But unfortunately, I do not see any message shown. What I am missing here.

It looks like you are creating a second (Symfony) request object here, which is not the same as the Slim PSR-7 request object.

If you have a symfony/form or symfony/http and another session package within the same project, they may affect each other because the symfony/http package also includes an internal session and flash component and this may not work together.

1 Like

Yes, you are correct as usual. I am using symfony http and symfony forms.

I am able to see all the sessions/flash values when i dump the values in the controller. Only in the twig its now available.

dump($this->session->getFlash()->all());

How should I handle in such cases?

For debugging purpose, you could try to dump the “flash” Twig variable within the template. You may also try to pass the Flash object directly as template variable.