Reputation: 10730
This may seem a simple example but I am stuck. I am watching a tutorial where we see a contact form that has its own get route to render a view that contains the already said contact form.
$app->get('/contact',function (Request $request, Response $response){
return $this->view->render($response,'contact.twig');
})->setName('contact');
Then we have a post that gets the posted data through that form (notice I am passing the data that has been collected from the form).
$app->post('/contact',function ($request,$response){
$data = $request->getParams();
//var_dump($data);
return $response->withRedirect($this->router->pathFor('contact.confirmed', ['data' => $data]));//https://github.com/slimphp/Slim/issues/1933
})->setName('contact');
Finally we have another get route to render a confirmation view that lets the user know that the information has been submitted successfully.
$app->get('/contact/confirmed',function(Request $request, Response $response, $data){
echo 'params are';
var_dump($data);//They never show! :(
return $this->view->render($response,'contact_confirm.twig',[
'data' => $request->getParams(),
]);//https://github.com/slimphp/Slim/issues/1579
})->setName('contact.confirmed');
In that confirmation view, I want to retrieve the data submitted in the post route just to call the user by their name but I get an error saying that $data
is empty.
I have been struggling on how to retrieve the user's name.
As a workaround, I have solved it by rendering the view right from the post route ...
$app->post('/contact',function ($request,$response){
$data = $request->getParams();
//var_dump($data);
return $response->withRedirect($this->router->pathFor('contact.confirmed', ['data' => $data]));//https://github.com/slimphp/Slim/issues/1933
})->setName('contact');
but then I wonder why bothering to use withRedirect()
function?
My question is, how do I pass data or parameters from a post route to a get route wher you use a withRedirect()
function? And in the get route, how do you retrieve those parameters? So I can pass them to its corresponding view.
Solved
Thanks to jmattheis this is how I solved it:
I just happened to learn how to use controllers in slim framework 3, so the ContactController.php
looks like:
<?php
namespace App\Controllers\contact;
use App\Controllers\Controller;
class ContactController extends Controller
{
public function show($request,$response)
{
return $this->c->view->render($response,'contact.twig');
}
public function store($request,$response)
{
echo 'storing comments in db ...';
$data = $request->getParams();
//var_dump($data);
//echo 'Name is: '.$data['name'];
$this->c->flash->addMessage('data', $data);
return $response->withRedirect($this->c->router->pathFor('contact.success'));
}
public function success($request,$response,$data)
{
//echo 'Data to be sent in the redirect: ';
$data = $this->c->flash->getFirstMessage('data');
//var_dump($data);
//die();
return $this->c->view->render($response,'contact_success.twig',compact('data'));
}
}
And I added the following code
session_start();
ini_set('date.timezone', 'America/Mexico_City');
right before
$app = new App([
'settings' => [
'displayErrorDetails' => true
]
]);
And that did the trick.
Upvotes: 0
Views: 3531
Reputation: 1579
Assuming that confirmation template is rendered only after form is being processed, there is no need to declare a separate GET route for such view.
So, keep the route that renders the form:
// This route renders the contact form.
$app->get('/contact', function ($request, $response) {
return $this->view->render($response, 'contact.twig');
})->setName('contact');
And render contact_confirm.twig
only as result of form being posted:
// This route is contact form processor.
$app->post('/contact', function ($request, $response) {
// Get submitted data.
$formData = $request->getParams();
// Process form data, e.g. store it, sending it somewhere...
// Render confirmation template, passing user name as template parameter.
$templateParams = [
'userName' => $formData['userName'] ?? 'Name unknown';
];
return $this->view->render($response, 'contact_confirmed.twig', $templateParams);
});
Upvotes: 0
Reputation: 11125
You can't transfer data over a redirect. The second parameter from the pathFor
method on the router is the array for the named paramters. That would be f.ex. id
in the route /user/{id}
then you'd had to put ['id' => 1]
in it.
If you $data
has a simple structur, then you could put them in the 3rd parameter which are the query params and later read them out with $request->getQueryParams()
$this->router->pathFor('contact.confirmed', [], $data);
Alternative, you could put the data in a session variable, slimphp/Slim-Flash is a library who that.
Example:
$app->post('/contact',function ($request,$response){
$data = $request->getParams();
$this->flash->addMessage('data', $data);
return $response->withRedirect($this->router->pathFor('contact.confirmed'));
})->setName('contact');
$app->get('/contact/confirmed',function(Request $request, Response $response, $data){
$data = $this->flash->getFirstMessage('data');
// ...
});
Upvotes: 3