Why does Silex say my route can't be found? - php

After updating a users profile, this line should redirect me to the page to show his profile:
return $app->redirect($app['url_generator']->generate('user/' . $id));
However, I get the following error:
RouteNotFoundException in UrlGenerator.php line 130: Unable to
generate a URL for the named route "user/1" as such route does not
exist.
And finally, this is the controller I'm trying to redirect to:
$app->match('/user/{id}', function (Request $request, $id) use ($app) {
$user = new User();
$user->find($id);
$team = new Team();
$team->find($user->data()->username);
if($team->exists()){
return $app['twig']->render('user.twig', [
'team_data' => $team->data(),
'user_data' => $user->data()
]);
}
else{
return $app['twig']->render('user.twig', [
'user_data' => $user->data()
]);
}
});
Can anyone tell my why this error is given even though I've defined the route?

Use $app['url_generator']->generate('user', ['id' => $id])
Silex (or rather the URL generator) handles the parameter processing for you.

Related

Laravel NotFoundHttpException on API

I have API URL like:
http://example.com/api/driverAcceptOrder?id=bee74e39-ff38-46a6-9e5d-6db799d2be8c&driverId=3453a3a9-7f58-434a-8dab-95c3469e6238
method is POST and it takes 2 parameter id and driverId
When I try to run this URL in postman I get:
Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException
Route
Route::post('driverAcceptOrder/{id}/{driverId}', 'Api\DriversController#driverAcceptOrder');
Controller
public function driverAcceptOrder(Request $request, $id, $driverId)
{
$order = Order::findOrFail($id);
$defs = OrderDefaultProgress::where('name', 'Driver OTW ke pelanggan')->first();
$driver = Driver::where('id', $driverId)->with('user')->first();
$order->update(['driver_id' => $driverId]);
return response()->json([
'data' => $driver,
'message' => 'Pengemudi Dalam perjalanan menuju pelanggan.'
], 200);
}
Note
Route is not restricted by Auth middleware (its public)
I've added exception to my VerifyCsrfToken file as protected $except = ['/api/*'];
Any idea?
your url is wrong
example.com/api/driverAcceptOrder?id=bee74e39-ff38-46a6-9e5d-6db799d2be8c&driverId=3453a3a9-7f58-434a-8dab-95c3469e6238
here after ? all is query paramter which is used in GET method to send data
Route::get('driverAcceptOrder',"..");
which is not found in your case that's why your getting
NotFoundHttpException
for your case url should be
example.com/api/driverAcceptOrder/bee74e39/3453a3a9-7f58-434a-8dab-95c3469e6238
this will be handel by
Route::post('driverAcceptOrder/{id}/{driverId}', 'Api\DriversController#driverAcceptOrder');
you can learn more about
GET and POST here https://www.w3schools.com/tags/ref_httpmethods.asp

Auth::user()->id returns "Trying to get property of non-object" -- Laravel 5.8

UPDATED 2
I made like and unlike method. But when I try to like the article, it returns an error. Route [login] not defined.
I am using passport API login. I am giving token for login etc... I login without a problem. I see the the pages only auth user can see. But it seems when I like the article, Auth:: doesn't understand user logged in or not. Maybe this is the problem. Because I am using Passport? So in the controller instead of Auth::
I used it like $user = $request->user(); (you can see the controller below.) But still same error popping when I like the article. Route [login] not defined.
controller
public function postLikeArticle( Request $request, $articleID )
{
$article = Article::where('id', '=', $articleID)->first();
$user = $request->user();
$article->likes()->attach( $user->id, [
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
]);
return response()->json( ['article_liked' => true], 201 );
}
public function deleteLikeArticle( Request $request, $articleID )
{
$article = Article::where('id', '=', $articleID)->first();
$user = $request->user();
$article->likes()->detach( $user->id );
return response(null, 204);
}
Routes
Route::middleware('auth:api')->group(function() {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::get('/articles/{id}/like', 'Api\ArticlesController#postLikeArticle');
Route::get('/articles/{id}/like', 'Api\ArticlesController#deleteLikeArticle');
});
If you need to see anymore file. please name it in the comment.
If you need the user to be authenticated then you need to be using the middleware that ensures that. In addition you need to also ensure that you are using the correct HTTP verbs depending on what you need to do, if anything your current definition is creating a conflict:
Route::middleware('auth:api')->post('/articles/{id}/like', 'Api\ArticlesController#postLikeArticle');
Route::middleware('auth:api')->delete('/articles/{id}/like', 'Api\ArticlesController#deleteLikeArticle');
You also need to ensure your front-end is using the correct verbs as well.
There are two reasons:
If you don't use the middleware you're basically saying those routes don't require authentication
If you're using the API guard to authenticate users then you need to explicitly use the auth:api middelware otherswise Laravel will attempt to authenticate the user using the default guard which is usually the session. When using an API you should not use the session
Your routes for like/dislike are not auth protected which means that the user might not be logged in, so you can group all routes requiring an authenticated user like this:
// public routes out of the group, for example:
Auth::routes();
Route::middleware('auth:api')->group(function() {
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::get('/articles/{id}/like', 'Api\ArticlesController#postLikeArticle');
// you cannot have same routes for both, so this
// Route::get('/articles/{id}/like', 'Api\ArticlesController#deleteLikeArticle');
// should be this:
Route::get('/articles/{id}/dislike', 'Api\ArticlesController#deleteLikeArticle');
});
Then either: Auth::id() or Auth::user()->id should give you the same. Or even the helper function so you don't need to worry for the imports..
auth()->id();
// or
auth()->user()->id;
instead of
Auth::user()->id
You can try this
auth()->user()->id
you can refer laravel documentation for more information
Few simple points should resolve your confusion:
"Trying to get property of a non object" means, Auth::user() is not an object which means it's null, you are trying to access a route publicly which needs an authenticated user which leads to our next point.
Routes which use functions postLikeArticle() and deleteLikeArticle() should be inside the authorization middleware 'auth:api'
You are using method get for both of your routes which use above functions, one should be using delete method.
You can use Auth::id() as a substitute of Auth::user()->id just to be short hand.
When using PASSPORT for authentication, you do not follow the usual Laravel way of user authorization hence Auth::user() is useless. In order to fetch the authenticated user, you need to use:
$user = $request->user();
Where $request is an instance of Illuminate\Http\Request
Here is an example for you:
Import the Request class in the beginning of the controller file:
use Illuminate\Http\Request;
and your controller logic:
public function postLikeArticle( Request $request, $articleID )
{
$article = Article::where('id', '=', $articleID)->first();
$user = $request->user();
$article->likes()->attach( $user->id, [
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
]);
return response()->json( ['article_liked' => true], 201 );
}
public function deleteLikeArticle( Request $request, $articleID )
{
$article = Article::where('id', '=', $articleID)->first();
$user = $request->user();
$article->likes()->detach( $user->id );
return response(null, 204);
}
I hope it helps

Calling a controller method from laravel middleware

I have a method in my base controller.php that formats all my responses to how I like it like so;
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if (!empty($errorMessages)) {
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
If I am calling it from another controller, i simply just call
return $this->sendError('Validation Error', $validator->errors(), 400);
But i am also using middleware for my JWT-Auth. Instead of re-writing the method, is there any way to call this controller method from inside middleware?
try this one in middleware by create of your controller
return (new yourChildController)->sendError('xyz errro',[],400)
First get the existing instance:
use Illuminate\Support\Facades\Route;
// ...
$myController = Route::getCurrentRoute()->getController();
Then call as you would normally, in OP's case:
return $myController->sendError('My error message.', [], 400);
Note that above is tested with Laravel 6.x release.

Call to a member function name() on null in laravel 5.4

When pressing my send button it's giving error like this-
Here is my routes web.php bellow-
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::resource('message/send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
Here is my controller MessageController.php bellow:
public function ajaxSendMessage(Request $request)
{
if ($request->ajax()) {
$rules = [
'message-data'=>'required',
'_id'=>'required'
];
$this->validate($request, $rules);
$body = $request->input('message-data');
$userId = $request->input('_id');
if ($message = Talk::sendMessageByUserId($userId, $body)) {
$html = view('ajax.newMessageHtml', compact('message'))->render();
return response()->json(['status'=>'success', 'html'=>$html], 200);
}
}
}
Resource routes should be named differently:
Route::prefix('ajax')->group(function () {
Route::resource('messages', 'MessageController', ['names' => [
'create' => 'message.new',
'destroy' => 'message.destroy',
]]);
});
Resource routes also point to a controller, instead of a specific method. In MessageController, you should add create and destroy methods.
More info at https://laravel.com/docs/5.4/controllers#restful-naming-resource-routes
You can't name a resource. Laravel by default name it, if you want to name all routes you must specify each one explicitly. It should be like this:
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::get('message/send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
Update
Another mistake of yours was trying to resource a single method. A Route::resource() is used to map all basic CRUD routes in Laravel by default. Therefore, you have to pass the base route and the class i.e:
<?php
Route::resource('message', 'MessageController');
Look at web.php line 28.
Whatever object you think has a name() method, hasn't been set, therefore you try and call a method on null.
Look before that line and see where it is (supposed to be) defined, and make sure it is set to what it should be!

Storing data in laravel happens once

Hi there best colleagues i've the following strange issue when i want to store data in my database but accomplish this task just once, when i want to store another data i get the following problem:
"Whoops something went wrong".
i've the following code in my controller
public function store()
{
$user = new User();
$user->username = Input::get('username');
$user->save();
return Response::json(array(
'error' => false,
'succes' => $user->toArray()),
200
);
}
and this is my routes.php
Route::group(array('prefix' => 'api/v1'), function() {
Route::resource('users', 'UserController',
array('except' => array('create', 'edit')));
});
I'm trying to post trough Postmen extension in Chrome and when i request a post to my uri:
http://www.bla.com/testLaravel/api/v1/users
(bla.com = localhost)
it just stores once my data and after that i get an error , i seriously can't figure out what the problem is. It would be great if someone can help me with it.
tnx

Categories