Zend Framework 2 redirect() with flashMessenger does not work

2.5k Views Asked by At

I have some controller with method_1(). In this method I call method_2(). In method_2() I have (try... catch) - block with defined flashMesseges and redirect.

$this->flashMessenger()->addErrorMessage("There are errors.");
return $this->redirect()->toRoute('home');

But it not work. But if I write as

$this->redirect()->toRoute('home');
$this->flashMessenger()->addErrorMessage("There are errors.");

All OK. In method_1() code

$this->flashMessenger()->addErrorMessage("There are errors.");
return $this->redirect()->toRoute('home');

good working. I don't understand. Can anybody help me?

Class A - redirect not working. And message add to session.

class A {
  public function manageAction()
  {
      $view = new ViewModel();

      $form = $this->getForm();
      $form = $this->fillForm($form);

      $view->form = $form;
      return $view;
  }

  public function fillForm($form)
  {
      try {
          // ...
      } catch (\Exception $e) {
          $this->flashMessenger()->addErrorMessage("Error");
          return $this->redirect()->toRoute('home');
      }
      return $form;
  }
}

Class B - redirect working. And message printed.

class B {
  public function manageAction()
  {
      $view = new ViewModel();

      $form = $this->getForm();
      $form = $this->fillForm($form);

      $view->form = $form;
      return $view;
  }

  public function fillForm($form)
  {
      try {
          // ...
      } catch (\Exception $e) {
          $this->redirect()->toRoute('home');
          $this->flashMessenger()->addErrorMessage("Error");
      }
      return $form;
  }
}

Why and how it work?

2

There are 2 best solutions below

1
On

The Plugin FlashMessenger , send your message to a waiting pool ( Through FlashMessenger Zend MVC Plugin ) which will be displayed on another page request ( Through ViewHelper FlashMessenger ) .

There are 4 types of messages that you can integrate with the Bootstrap Notifications ( error, info , default , success ) .

Now let's practice

In Action within the Controller , you must enter your message and your brand :

use Zend\Mvc\Controller\Plugin\FlashMessenger;

public function registerAction(){
  if($formValid){
      $this->flashMessenger()->addSucessMessage('Saved!');
  } else{
      $this->flashMessenger()->addErrorMessage('Fail!');
  }

  //redirect to other route and show message
  return $this->redirect()->toRoute('app');
}

In View ( .phtml ) , you only need to use :

#show messages of addErrorMessage();
echo $flash->render('error',   array('alert', 'alert-dismissible', 'alert-danger'));
#show messages of addInfoMessage();
echo $flash->render('info',    array('alert', 'alert-dismissible', 'alert-info'));
#show messages of addMessage();
echo $flash->render('default', array('alert', 'alert-dismissible', 'alert-warning'));
#show messages of addSucessMessage();
echo $flash->render('success', array('alert', 'alert-dismissible', 'alert-success'));

In View , if using Bootstrap :

 $flash = $this->flashMessenger();
 $flash->setMessageOpenFormat('<div>
     <button type="button" class="close" data-dismiss="alert" aria-hidden="true">
         &times;
     </button>
     <ul><li>')
     ->setMessageSeparatorString('</li><li>')
     ->setMessageCloseString('</li></ul></div>');


 echo $flash->render('error',   array('alert', 'alert-dismissible', 'alert-danger'));
 echo $flash->render('info',    array('alert', 'alert-dismissible', 'alert-info'));
 echo $flash->render('default', array('alert', 'alert-dismissible', 'alert-warning'));
 echo $flash->render('success', array('alert', 'alert-dismissible', 'alert-success'));

Now 's a hack , if you want to view the FlashMessages on the screen without resquest ou redirect page ( Ideal for form errors , which you do not redirects or AJAX to another page ) , use renderCurrent and clear.

echo $flash->renderCurrent('error', array('alert', 'alert-dismissible', 'alert-danger'));

If you want to deepen better at it, follow the links Official Zend 2 documentation , gives a tried on available methods , will help a lot :

VIEW -> http://framework.zend.com/manual/current/en/modules/zend.view.helpers.flash-messenger.html

CONTROLLER -> http://framework.zend.com/manual/current/en/modules/zend.mvc.plugins.html#zend-mvc-controller-plugins-flashmessenger

1
On

The redirect() plugin returns Response object. You should return it in the Action.

Update: I recommend to move try/catch to the action.

class A {
  public function manageAction()
  {
      $view = new ViewModel();

      $form = $this->getForm();

      try {
         $this->fillForm($form);
      } catch (\Exception $e) {
          $this->flashMessenger()->addErrorMessage("Error");
          return $this->redirect()->toRoute('home');
      }

      $view->form = $form;
      return $view;
  }

  public function fillForm($form)
  {
          // ...
  }
}