Reputation: 17309
I'm trying for the first time to set and then display a flash message in a Symfony2 application. A flash message being set is not cleared once displayed for the first time.
I set a flash message in a controller action:
public function startAction()
{
if (!$this->hasError()) {
$this->get('session')->setFlash('test_start_error', '');
return $this->redirect($this->generateUrl('app', array(), true));
}
}
And in the corresponding view I display an error notification if the relevant flash key is set:
{% if app.session.hasFlash('test_start_error') %}
error content here
{% endif %}
Under the correct error conditions, the controller sets the flash message and the relevant error content is presented in the view.
Once displayed, the flash message is presented again request after request.Examining the relevant session data via var_dump($this->get('session')->getFlashBag());
reveals that the flash content remains in the session.
I was under the impression that a flash message, having been displayed once, is removed from the session. This is not happening for me.
Clearly I'm doing something wrong - what is it?
Upvotes: 3
Views: 5117
Reputation: 2664
app.session.hasFlash('test_start_error')
This doesn't actually destroy flash message, the next part does
{{ app.session.flash('test_start_error') }}
In other word, you need to actually use the flash message, than it will be destroyed. You just checked if it exist.
EDIT: As per thecatontheflat request, here are corresponding methods from FlashBag (Symfony > 2.0.x) class.
The "has" method:
public function has($type)
{
return array_key_exists($type, $this->flashes) && $this->flashes[$type];
}
The actual get method:
public function get($type, array $default = array())
{
if (!$this->has($type)) {
return $default;
}
$return = $this->flashes[$type];
unset($this->flashes[$type]);
return $return;
}
As you can see it only unsets the session, only when you request the actual flash message, not when you check for its existence.
In Symfony 2.0.x flash behavior is different. Flashes literally last for one request, used or not. Or at least I'm under that impression after browsing the code, and testing it locally.
EDIT2:
Oh yeah, the actual sollution in your case, if it wasn't obvious by now, is to use removeFlash inside if statement like this:
{% if app.session.hasFlash('test_start_error') %}
error content here
{{ app.session.removeFlash('test_start_error') }}
{% endif %}
Thanks to thecatontheflat, for remanding me that I haven't actually provided a solution for the given problem. :)
P.S. removeFlash method is deprecated in v2.1, and will be removed from v2.3. Anyway if you look inside the Session class, you can see that it only acts like middle man that calls get method from FlashBag class, and that method actually does the removing.
Upvotes: 5