Flash messages in Slim 4

Hello there!

I try to add a flash message in my controller:

$this->get('flash')->addMessage('foo', 'bar');

I get following error message: Call to undefined method App\Controllers\TestController::get().

My route:
$group->post('/test', TestController::class . ':register');

My Container:

$container->set('flash', function(){
    return new \Slim\Flash\Messages();
});

Can please someone have a look?
Thank you very much!

$this in that context appears to be the TestController class which likely doesn’t have a get method. You are likely confusing it with a container instance.

What does your TestController class look like?

If it helps, I wrote that:

  private function flashCodes(array $codes, string $key) {
    $allCodes = array_merge(Params::getFromSession($key, []), $codes);
    Params::putInSession($key, $allCodes);
  }

  
  protected function addFlashInfoCodes(array $codes) {
    $this->flashCodes($codes, Constantes::KEY_FLASH_MESSAGES_INFO);
  }

  
   protected function addFlashErrorCodes(array $codes) {
    $this->flashCodes($codes, Constantes::KEY_FLASH_MESSAGES_ERROR);
  }

  
  protected function addFlashData(array $data) {
    $allData = array_merge(Params::getFromSession(Constantes::KEY_FLASH_DATA, []), $data);
    Params::putInSession(Constantes::KEY_FLASH_DATA, $allData);
  }

  protected function getFlashData(string $key, $default = null) {
    $result = $default;
    $flashData = $this->usual->flashData;
    if (is_array($flashData) && isset($flashData[$key])) {
      $result = $flashData[$key];
    }
    return $result;
  }


  protected function flashRedirect(
      Request $request, 
      Response $response, 
      string $routeName, 
      array $routeParams = [], 
      array $errorCodes = [],
      array $infoCodes = [], 
      array $data = [],
      int $httpStatusCode = 302
  ): Response {
    $this->addFlashErrorCodes($errorCodes);
    $this->addFlashInfoCodes($infoCodes);

    $loggerUid = $this->getLoggerUid();

    $data2 = array_merge($data, [
      'loggerUid' => $loggerUid
    ]);
    $this->addFlashData($data2);
    
    return $this->responder->redirectToRoute($request, $response, $routeName, $routeParams, $httpStatusCode);
  }

In your case $this points to the controller instance. In Slim 4 you may use dependency injection or you use the container instance instead.

My TestController looks like this:

namespace App\Controllers;

use App\Exceptions\NotFoundHttpException;
use PDO;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Exception\HttpNotFoundException;
use Slim\Views\Twig;

class TestController{
  protected $view;
  protected $db;

  public function __construct(Twig $view, $db){
    $this->view = $view;
    $this->db = $db;
  }

  public function register(Request $request, Response $response, $args){
    $data = $request->getParsedBody();

     // DB Insert

      $this->get('flash')->addMessage('registered', true);

     //...

  }
}

In that context, $this is referring to your TestController instance. You will want to bring your instance of Flash into your controller just like you are bringing in your view and the $db. Then you can refer to it as $this->flash->addMessage(...) instead of $this->get(…)`. Something like this (untested).

namespace App\Controllers;

use App\Exceptions\NotFoundHttpException;
use PDO;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Exception\HttpNotFoundException;
use Slim\Flash\Messages as Flash;
use Slim\Views\Twig;

class TestController{
  protected $view;
  protected $db;
  protected $flash;

  public function __construct(Twig $view, $db, Flash flash$){
    $this->view = $view;
    $this->db = $db;
    $this->flash = $flash;
  }

  public function register(Request $request, Response $response, $args){
    $data = $request->getParsedBody();

     // DB Insert

      $this->flash->addMessage('registered', true);

     //...

  }
}
1 Like