First time Laravel facing NotFoundHttpException - php

I'm following flynsarmys' laravel tutorial. Everything went well until the second part where I put the index for ProjectsController, when I tested to navigate to 15todo.app:8000/projects in browser the app throws NotFoundHttpException.
routes.php
Route::get('/', function () {
return view('welcome');
});
Route::resource('projects', 'ProjectsController');
// Route::resource('tasks', 'TasksController');
Route::resource('projects.tasks', 'TasksController');
Route::bind('tasks', function($value, $route) {
return App\Task::whereSlug($value)->first();
});
Route::bind('projects', function($value, $route) {
return App\Project::whereSlug($value)->first();
});
ProjectsController.php
public function index()
{
return view('projects.index');
}
I have googled and searched, but I still haven't find a clue of why this is happening. If I checked php artisan route:list it showed like this
$ php artisan route:list
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
| | GET|HEAD | / | | Closure | |
| | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController#index | |
| | GET|HEAD | projects/create | projects.create | App\Http\Controllers\ProjectsController#create | |
What am I doing wrong? Help...
My dev env is homestead on windows. For the console I'm using Git Bash (MinGW). My 15todo.app:8000 is up and showing "Laravel 5" and random quotes about simplicity.

You need to actually create the view. Save it in the /app/resources/views/projects/ directory as index.blade.php. Reference the views documentation here.
You can either create a new PHP/HTML file, but the best practice is to use the Blade template engine. For example:
#extends('app')
#section('content')
<!-- your content here -->
{{ 'escaped string' }}
{!! 'non escaped <strong>string</strong>' !!}
#endsection
#stop
Read up a little bit more on the docs for the view, and check out this video on Laracasts.

Related

laravel - how to add prefix in all url without affecting route existing

i have url like this mysite.com/company, i want add prefix to url to become mysite.com/home/company.
I've tried to add a route group, but that requires me to update all existing routes.
can i add a prefix in all url without affecting the existing route ?
i used laravel 5.6
I have created a sandbox so that you can view and play around with the code used for this answer.
I know the sandbox uses a different Laravel version (version 7), but looking at the documentation for version 5.6 the routing does not seem to be that much different than that of version 7.
What you can do is wrap the already existing routes inside an anonymous function and assign it to a variable, you can then use this variable and pass it as a parameter to the group routing function along with a prefix, e.g.
$routes = function() {
Route::get('company', function () {
return 'companies';
});
Route::get('company/{company}', function ($company) {
return "company $company";
});
Route::delete('company/{company}', function ($company) {
return "deleting company $company...";
});
Route::get('company/{company}/staff', function ($company) {
return "staff list for company $company...";
});
};
Route::prefix('/')->group($routes);
Route::prefix('/home')->group($routes);
When running php artisan route:list the following is returned:
+--------+----------+------------------------------+------+---------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+------------------------------+------+---------+------------+
| | GET|HEAD | api/user | | Closure | api |
| | | | | | auth:api |
| | GET|HEAD | company | | Closure | web |
| | GET|HEAD | company/{company} | | Closure | web |
| | DELETE | company/{company} | | Closure | web |
| | GET|HEAD | company/{company}/staff | | Closure | web |
| | GET|HEAD | home/company | | Closure | web |
| | GET|HEAD | home/company/{company} | | Closure | web |
| | DELETE | home/company/{company} | | Closure | web |
| | GET|HEAD | home/company/{company}/staff | | Closure | web |
+--------+----------+------------------------------+------+---------+------------+
You can see above that the routes can now be accessed via both / and home/, e.g. http://example.com/company and http://example.com/home/company without the need for duplicating routes.
If you need to add any more prefixes in the future you just simply add a new Route::prefix("<prefix>")->group($routes); to the routes file.
The update below is in response to the comment provided by OP.
To get this correct you are looking for a way to automatically convert all instances of the url function from url('someurl') to url('home/someurl'), e.g.
url('company') will become url('home/company')
url('knowledgebase') will become url('home/knowledgebase')
If so then I have two solutions for you:
Can you not simply do a search and replace within the IDE you are using?
You can override Laravel's url helper function to prefix all path's with home/, to do so you can do the following:
I have created another sandbox so that you can view and play around with the code used for this answer.
First create a helpers.php file anywhere within your Laravel application, when testing this code I placed the file in the root directory of the application, e.g. /var/www/html/helpers.php.
Second you need to override the url helper function, to make sure you don't lose any functionality I grabbed the original source code of the function from Laravel's github repository. I then modified it to include the prefix, so place the following in the new helpers.php file:
<?php
use Illuminate\Contracts\Routing\UrlGenerator;
if (! function_exists('url')) {
/**
* Generate a url for the application.
*
* #param string|null $path
* #param mixed $parameters
* #param bool|null $secure
* #return \Illuminate\Contracts\Routing\UrlGenerator|string
*/
function url($path = null, $parameters = [], $secure = null)
{
if (is_null($path)) {
return app(UrlGenerator::class);
}
$path = "home/$path";
return app(UrlGenerator::class)->to($path, $parameters, $secure);
}
}
Next, you need to load your helpers.php file before Laravel loads their helper functions, otherwise it wont load, to do so add require __DIR__.'/../helpers.php'; to public/index.php before require __DIR__.'/../vendor/autoload.php';, e.g.
require __DIR__.'/../helpers.php';
require __DIR__.'/../vendor/autoload.php';
Now you can use the new url function within your application, I have given some examples in the web.php routes file:
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
echo url("company");
echo "<br/>";
echo url("knowledgebase");
});
The above will output to the webpage:
http://example.com/home/company
http://example.com/home/knowledgebase
Now if you need to change the url function slightly to more fit your requirements you can do so by modifying it within the helpers.php file.

Framework PHP Route - Error 404 Not found

In Laravel, I need to edit user created by Auth/RegisterController, but using the controller that I created, example ProfileController. But when I try access by a a:href button, show 404 Error.
Code:
web.php
Route::group(['middleware' => ['auth']], function(){
Route::resource('profile', 'ProfileController')->except(['edit']);
Route::get('profile/{profile}/edit', ['as' => 'profile.edit', 'uses' => 'ProfileController#edit']);
});
Auth::routes();
app.blade.php
<a href="{{route('profile.edit',['profile'=>auth()->user()->id])}}" class="btn btn-primary">
{{auth()->user()->email}}
</a>
ProfileController
public function edit($profile)
{
$user = \App\User::findOrFail($profile);
return view('profile.edit', compact('user'));
}
List Routes
| | POST | profile | profile.store | App\Http\Controllers\ProfileController#store | web,auth,guest |
| | GET|HEAD | profile | profile.index | App\Http\Controllers\ProfileController#index | web,auth,guest |
| | GET|HEAD | profile/create | profile.create | App\Http\Controllers\ProfileController#create | web,auth,guest |
| | DELETE | profile/{profile} | profile.destroy | App\Http\Controllers\ProfileController#destroy | web,auth,guest |
| | PUT|PATCH | profile/{profile} | profile.update | App\Http\Controllers\ProfileController#update | web,auth,guest |
| | GET|HEAD | profile/{profile} | profile.show | App\Http\Controllers\ProfileController#show | web,auth,guest |
| | GET|HEAD | profile/{profile}/edit | profile.edit | App\Http\Controllers\ProfileController#edit | web,auth,guest |
Someone can help me?
Tks,
Aguiar, Adson M.
Welcome to SO!
Like #lagbox mentioned, you can just keep the
Route::resource('profile', 'ProfileController');
without the ->except() to have the exact same edit route automatically generated for you.
Furthermore, you can simplify your controller action to:
public function edit(User $profile)
{
return view('profile.edit', compact('profile'));
}
This uses type hinting to automatically have the dependency injection resolve a User instance for you, identified by the key passed in with the {profile} parameter.
You would then have to go with $profile in your profile/edit.blade.php, unless you want to do something like return view('profile.edit', ['user' => $profile]);.
It might be a good idea to name the parameters like your Models. Resource routes usually base completely on the Model's names, so profile is not a good choice for User routes. You might either use Route::resource('user', 'ProfileController') (or even UserController for that matter), or if you want to stick with profile, but want $user as a parameter, you would have to create all routes by yourself like Route::get('profile/{user}/edit', 'ProfileController').
Also, writing route('profile.edit',['profile'=>auth()->user()]) works too, and has the advantage that it would not break when the user is not authenticated.
All that said, your code should still work. Try to use a find() instead of a findOrFail() and dd($user); in the following line to make sure your route is working. If you see the dump, it is probably null, meaning the id passed is not valid, which would be really odd.
If you can post the full generated link of the anchor tag and the outcome of the dd, I'll be happy to help.

Laravel API Routes Return 404

I am using Laravel 5.6 and I'm getting HTTP404 responses on existing routes in routes/api.php which I define as follows:
Route::middleware('auth:api')->post('/account/plan', 'Account\BillingController#updatePlan');
Route::middleware('auth:api')->put('/account/plan', 'Account\BillingController#unsubscribe');
Route::middleware('auth:api')->patch('/account/plan', 'Account\BillingController#resubscribe');
When I use axios.post() on these routes and include the _method parameter I get a 404 response on the PUT and PATCH routes. I have also tested axios.put()/axios.patch() in place of using post() with and without the inclsion of the _method parameter. I have also confirmed these are being correctly represented by artisan route:list:
| | POST | api/account/plan | | App\Http\Controllers\Account\BillingController#updatePlan | api,auth:api |
| | PUT | api/account/plan | | App\Http\Controllers\Account\BillingController#unsubscribe | api,auth:api |
| | PATCH | api/account/plan | | App\Http\Controllers\Account\BillingController#resubscribe | api,auth:api |
Example of the Axios Call:
axios.post(url,{_method:"PUT",confirm:"unsubscribe"})
.then(response => callback(response.data))
.catch(error => console.log(error))
When I define these same routes as follows they all work as intended:
Route::middleware('auth:api')->post('/account/plan', 'Account\BillingController#updatePlan');
Route::middleware('auth:api')->post('/account/unsubscribe', 'Account\BillingController#unsubscribe');
Route::middleware('auth:api')->post('/account/resubscribe', 'Account\BillingController#resubscribe');
I am able to separate endpoints by the request method on other routes I am unsure why these are creating a problem. Can someone explain why I get the 404 responses and how I can avoid them?
Since it seems you are doing evrything fine maybe by following laravel more strict conventions on defining routes you won't encounter the problem? Try like this:
Route::middleware(['auth:api'])->group(function () {
Route::post('/account/plan', 'Account\BillingController#updatePlan');
Route::put('/account/plan', 'Account\BillingController#unsubscribe');
Route::patch('/account/plan', 'Account\BillingController#resubscribe');
});

Laravel route allow any parameter not working

Any help why this is not working,I am using Laravel 5.4 version ,this is are my routes
app\Providers\RouteServiceProvider.php
public function map()
{
$this->mapWebRoutes();
$this->mapExampleRoutes();
}
protected function mapExampleRoutes()
{
Route::prefix('example')
->middleware('example')
->namespace($this->namespace.'\\Examle')
->group(base_path('routes/example.php'));
}
routes\example.php
Route::get('/{any}', function () {
return view('example.app');
})->where('any', '.*');
$ php artisan route:list
+--------+-----------+-----------------+------+----------+-------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+-----------------+------+----------+-------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | example/{any} | | Closure | example |
+--------+-----------+-----------------+------+----------+-------------+
The problem is when I try to access /example it returns not found (NotFoundHttpException) ,
other routes are working , for example, /example/login .
any idea why this one is not working ?
Route::get('{any?}', function () {
return view('example.app');
})->where('any', '.*');
I removed the leading slash (/) and added a question mark (?) to indicate the slug is optional.

Laravel controller action returns error 404

I'm getting a 404 error when trying to access a route linked to a controller action.
I have the route defined like this in my routes.php file.
Route::controller('error', 'ErrorsController');
The ErrorsController class looks as follows.
class ErrorsController extends BaseController {
public function __construct()
{
// vacio
}
public function getIndex()
{
return View::make('error.accessdenied');
}
public function getAccessDenied()
{
return View::make('error.accessdenied');
}
}
I have a view with a link to chek if it is working properly. The link is created as follows
{{ HTML::linkAction('ErrorsController#getAccessDenied', 'Error') }}
When I click on the link the page moves to the URL 'mytestdomain.com/error/access-denied' returning an 404 error, but when I access the URL 'mytestdomain.com/error' it works perfectly.
Any idea on what I'm doing wrong?
EDIT:
Running the command php artisan routes these are the routes pointing to ErrorsController:
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
| | GET|HEAD error/index/{one?}/{two?}/{three?}/{four?}/{five?} | | ErrorsController#getIndex | | |
| | GET|HEAD error | | ErrorsController#getIndex | | |
| | GET|HEAD error/access-denied/{one?}/{two?}/{three?}/{four?}/{five?} | | ErrorsController#getAccessDenied | | |
| | GET|HEAD|POST|PUT|PATCH|DELETE error/{_missing} | | ErrorsController#missingMethod | | |
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
Only the sencond and the fourth ones are working.
It looks as though specifying the route in the way you have won't work. This type of routing only works for RESTful requests. See >http://laravel.com/docs/4.2/controllers#restful-resource-controllers>.
You might have to explicitly specify the route using Route::get/post.
Somehow I found the problem.
For some reason, my apache server doesn't rewrite mytestdomain.com/error/ * route. Probably is something related with the word error and the apache module mod_rewrite.
Anyway, defining the route as follows solves the problem.
Route::controller('fail', 'ErrorsController');

Categories