Buy

Adding a Flash Message

After registration, let’s make the new user feel loved by giving them a big happy success message! Symfony has a feature called flash messages, which is perfect for this. A flash is a message that we set to the session, but that disappears after we access it exactly one time.

After registration, grab the session object from the request and get an object called a “flash bag”. Set a message on it using add:

// src/Yoda/UserBundle/Entity/Controller/RegisterController.php
// ...

if ($form->isValid()) {
    // .. code that saves the user

    $request->getSession()
        ->getFlashBag()
        ->add('success', 'Welcome to the Death Star, have a magical day!')
    ;

    $url = $this->generateUrl('event');

    return $this->redirect($url);
}

Rendering a Flash Message

That’s it! Now, if a flash message exists, we just need to print it on the page. Let’s do that in base.html.twig. The session object is available via app.session. Use it to check to see if we have any success flash messages. If we do, let’s print the messages inside a styled container. You’ll typically only have one message at a time, but the flash bag is flexible enough to store any number:

{# app/Resources/views/base.html.twig #}

<body>
    {% if app.session.flashBag.has('success') %}
        <div class="alert alert-success">
            {% for msg in app.session.flashBag.get('success') %}
                {{ msg }}
            {% endfor %}
        </div>
    {% endif %}

    <!-- ... -->

The success key is just something I made up. With this setup, whenever we need to show a happy message, we just need to set a success flash message and it’ll show up here!

Let’s test it out. We register, the flash message is set, and then it’s displayed after the redirect. Nice!

Leave a comment!

  • 2015-01-08 weaverryan

    Hi Mel!

    It looks ok to me! It's possible that something else is "consuming" your flash messages, which will erase them from the flash. One first tip is that if you click the web debug toolbar to go into the profiler, then you click into the Request tab, you can see a list of the flash messages that Symfony knows about.

    Here's what I'd do to debug:

    1) Add a var_dump($request->getSession()->getFlashbag()->get('success'));die; in your controller code that you pasted above right after you set the flash message. I'm pretty sure this will return the message, but let's just make sure nothing strange is happening.

    2) Remove the above debug code, then put it in whatever controller you're redirecting to. Is it there? If it is, the nit *is* successfully being transferred across requests, but then something else might be reading/clearing it when you read the template.

    3) Try a key other than "success" to see if that changes anything.

    I'm sure it's something small - this is one of those "it just kinda works" type of features :).

  • 2015-01-08 Mel

    Hi Knp,

    I hope you could help me with my flashbag issue.
    I'm new with Symfony and I'm using FOSRESTBUNDLE in my sample project. I can't seem to get the flashbag to display.

    Here is my code:

    Controller

    public function postGenderAction(Request $request)
    {
    $form = $this->newGenderAction();
    $form->handleRequest($request);
    $newGender = $form->getData();
    $form->getErrorsAsString(true);

    if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();
    $em->persist($newGender);
    $em->flush();

    // Redirect to the list of genders.
    $nextAction = $form->get('saveAndAdd')->isClicked() ? 'api_1_new_gender' : 'api_1_get_genders';

    // Adds a flashbag message.
    $request->getSession()->getFlashbag()
    ->add('success', 'The new gender has been created successfully!');

    $routeOptions = array(
    'id' => $newGender->getId(),
    '_format' => $request->get('_format')
    );

    return $this->routeRedirectView($nextAction, $routeOptions, Codes::HTTP_CREATED)
    ;
    }

    Twig

    {#Flashbag#}
    {% if app.session.flashbag.has('success') %}
    <div class="alert alert-success" role="alert">
    {% for msg in app.session.flashbag.get('success') %}
    {{ msg }}
    {% endfor %}
    </div>
    {% endif %}

    Thanks in advance!