I used to create functions in controllers like this with Laravel 5.8 and I was able to handle when the item was not found redirecting the user to the index page with an error notification.
public function edit($id)
{
$template = Template::find($id);
if ($template) {
return view('admin.templates.edit', compact(['template']));
}
$this->setNotifications('error', 'Not found');
return redirect()->route('admin.templates.index');
}
Now with Laravel 6 the function declaration has changed and if the item is not found, it displays the default not found page directly, ignoring the code in the function and I'm not able handle the not found error as I used to do.
public function edit(Template $template)
{
if ($template) {
return view('admin.templates.edit', compact(['template']));
}
$this->setNotifications('error', 'Not found');
return redirect()->route('admin.templates.index');
}
Is there a way to use the Laravel 6 way and handle what happens when the item is not found at the same time?
Related
Im currently using Lumen 8. Im having issues with routing. The controllers work fine for get methods without parameters but I get a "Bad Routes exception" when I pass parameters
$router->get('/accounts', 'AccountsController#index');
$router->get('/accounts/{id:[\d]+}', 'AccountsController#show');
For example for the first route, localhost/accounts it displays the required data. The second route however when localhost:8002/accounts/1 it returns the error.
The routes are defined in an AccountsController
public function index(){
$data = $this->collection(Account::all(), new AccountsTransformer());
return response()->json($data);
}
public function show($id){
try{
return $this->item(Account::query()->findOrFail($id), new AccountsTransformer());
} catch (ModelNotFoundException $e){
response()->json(['error'=>['message'=>'Account not found']]);
}
}
In symfony how can I redirect to a custom 404 error page from a controller when I don't find an element in the database?
For example:
if ( empty($db_result) ) {
/* DO REDIRECT */
} else {
return $this->render('default/correct.html.twig');
}
Try this way:
if ( is_null($db_result) ) {
throw $this->createNotFoundException();
} else {
return $this->render('default/correct.html.twig');
}
If the route provides a unique value (often an ID, but it could be a username or simple text), then the SensioFrameworkExtraBundle ParamConverter can fetch an entity (a database record) automatically.
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* #Route("/blog/{id}")
* #ParamConverter("post", class="SensioBlogBundle:Post")
*/
public function showAction(Post $post)
{
}
That is so common there is an even easier and quicker way, by using the method signature on its own:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
/**
* #Route("/blog/{id}")
*/
public function showAction(Post $post)
{
// $post will be the database record - if it exists
}
In a 'prod' environment (the live server), if there is no record in the 'post' table, id:1 (for example) when you visit /blog/1, then the framework will make a 404 error for you.
If you want to do the search by yourself (or its more complex), you can make a 'NotFoundHttpException', or use the controller shortcut to do so:
public function indexAction(/* parameters, like Request, or maybe $id */)
{
// retrieve the object from database
$product = ...;
if (!$product) {
throw $this->createNotFoundException('The product does not exist');
}
return $this->render(...);
}
I'm new in Laravel and I'm trying to create a View in Acelle (app based on Laravel). I read a lot of tutorials, but I've not been luck with this problem.
I created the view "lol.blade.php" on /resources/views folder with this code:
HELLO (just hello)
The Route:
Route::get('lol', function()
{
if (view()->exists('lol')) {
//return 'helloooo'; <--- it works
return view('lol');
} else {
return 'not exists';
}
});
The code knows the view exists, but the url (localhost/acelle/public/lol) prints this message:
"Whoops, looks like something went wrong."
I can't solve the problem with tutorials. I followed all the steps about creating views in Laravel, but I don't know why the view prints that message.
Please help!
PS: Laravel version: 5.2.45
EDIT:
In console [network] shows Error 500. and laravel.log prints 59 lines. but the first line show:
[2017-07-14 14:08:20] production.ERROR: ErrorException: Undefined index:controller in /home/acelle/public_html/acelle/app/Providers/AppServiceProvider.php:20
You posted this in the comments:
app('view')->composer('*', function ($view) {
$action = app('request')->route()->getAction();
$controller = class_basename($action['controller']);
list($controller, $action) = explode('#', $controller);
$view->with(compact('controller', 'action'));
});
Your issue is that this route uses a closure, and has no controller:
Route::get('lol', function() {});
Therefore, $action['controller'] doesn't exist and throws a warning as a result. You'll want to check isset($action['controller']) before doing the rest of your code that uses the controller variable.
Already solved!!
SOLUTION:
creating a controller : MiwebController.php
<?
namespace Acelle\Http\Controllers;
class MiwebController extends Controller
{
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
public function index()
{
return view('lol');
}
}
?>
routes.php:
Route::get('lol', 'MiwebController#index');
It works fine. Thank you!
As I'm beggining with Laravel, this should be a simple one:
How can I define a custom view to be rendered when my route model binding just can't find the given ID?
Here's my route:
Route::get('/empresa/edit/{empresa}', 'EmpresaController#edit');
Here's my controller's method:
public function edit(Empresa $empresa)
{
if ((!isset($empresa)) || ($empresa == null)):
//I get that this won't work...
return 'Empresa não encontrada';
endif;
return view('Empresa.dadosEmpresa')->with('empresa', $empresa)->with('action', URL::route('empresa_update', ['id', $empresa->id]))->with('method', 'PATCH');
}
Here's my "attempt" to use an error handler:
public function render($request, Exception $exception)
{
if ($e instanceof ModelNotFoundException)
{
//this is just giving me a completely blank response page
return 'Empresa não encontrada';
}
return parent::render($request, $exception);
}
How is this really done?
1. The formal way (but would it be really needed to customize in this way?)
First of all, what Laravel does is, if there is not Model Row in DB with the given id, it sends 404 response, automatically.
If a matching model instance is not found in the database, a 404 HTTP response will be automatically generated.
So if you wanna show your customized view, you need to customize error handling.
So in RouteServiceProvider file, make sure it throws custom exception using 3rd param like follwoing:
public function boot()
{
parent::boot();
Route::model('empresa', App\Empresa::class, function () {
throw new NotFoundEmpresaModelException;
});
}
And then do same thing in the render function as you tried before.
2. The casual way - Pretty easy to go
I d rather suggest that you do not use model injection ability, but handle the request yourself.
So take the empresa id value as it is, and then try to find the right data, and if not found, then make your custom logic. That should be pretty easy to go.
public function edit(Request $request, $empresa)
{
$empresaObj = Empresa::find($empresa);
if (!$empresa) {
return 'Empresa não encontrada';
}
return view('Empresa.dadosEmpresa')->with('empresa', $empresa)->with('action', URL::route('empresa_update', ['id', $empresa->id]))->with('method', 'PATCH');
}
I have two routes /alpha and /beta configured in yml. In alphaAction a notice is placed in the flashbag and a redirecttoroute occurs. In betaAction the notice in the flashbag is read.
Sometimes I get 2 notices when I try /alpha in the browser and sometimes I get one notice.
Can someone explain what is happening, what I'm doing wrong.
public function alphaAction()
{
$this->get('session')->getFlashBag()->add("notice",mt_rand());
return $this->redirectToRoute("beta");
}
public function betaAction()
{
$notices= $this->get('session')->getFlashBag()->get('notice');
return new Response(implode($notices,", "));
}
Using the add method I could reproduce the issues you described. This can be fixed by using the set method and not the add (or setFlash) method.
public function alphaAction()
{
$this->get('session')->getFlashBag()->set("notice",mt_rand());
return $this->redirectToRoute("beta");
}
public function betaAction()
{
$notices= $this->get('session')->getFlashBag()->get('notice');
return new Response(implode($notices,", "));
}