why i am getting No query results for model in laravel? - laravel

When i search by city name which is available in my database table it will show the result but when i search by unknown city which is not available in my database table it says -No query results for model [App\City]. i am sharing you the code and screenshot see error screenshot
actually i want to redirect to 401 page if the city is not found in my database table
Here is my route
Route::get('teacher-jobs-by-city/{city}','TeacherJobsController#by_location');
Here is my function
public function by_location($location_id='')
{
$data= array();
$location = City::where('slug',$location_id)->where('status','1')->firstOrFail();
$items= Subject::orderBy('id','asc')->get();
$data['location']=$location;
//$subjects = [''=>'Select Subject'] + Subject::lists('subject_title','id')->toArray();
//$city = [''=>'Select City'] + City::lists('name','id')->toArray();
$active_class ='Select Subject to see job Openings';
return view('frontend.teacherjobs.by_location',compact('active_class','data','items'));
}

That's because you are using the firstOrFail() method, that as named, fails if theres no result by throwing an Exception that will be redered as "No query results for model ..." message.
If you want to it don't fail, you can:
Surround your query with a try-catch block, handling the exception and return some message
Replace the firstOrFail() method by first()

You can handle that kind of error by modifying the way Illuminate\Database\Eloquent\ModelNotFoundException Exception are handle. In the App\Exceptions\Handler class change the render method to look like this
public function render($request, Exception $exception)
{
if($exception instanceof ModelNotFoundException){
return redirect("/error_page", 401)->with('error', $e->getMessage());
}
return parent::render($request, $exception);
}
Within the redirect your must put the route to which you want to be redirected, I put /error_page just for sample purpose.
You can learn more on Error Handling'
Don't forget to import the ModelNotFoundException like this use Illuminate\Database\Eloquent\ModelNotFoundException;

Adding on to the answer by Elias Soares, This happens because laravel generates an "Illuminate\Database\Eloquent\ModelNotFoundException" exception if firstOrFail don't return results.
Reference: https://laravel.com/docs/5.8/eloquent#retrieving-single-models
It's upto you how you want to handle this exception. If using firstOrFail -> to first() solution
After replacing firstOrFail with first, You would get the error: "Trying to get property of non object", That's because your query didn't fetched anything, so it won't have attribute. For that you can place a check on the results of your query.
$location = City::where('slug',$location_id)->where('status','1')->first();
!empty($location->attribute)?$location->attribute:null;

Replace this:
$location = City::where('slug',$location_id)->where('status','1')->firstOrFail();
With this:
$location = City::where('slug',$location_id)->where('status','1')->first();

Related

How i can get the variable data as string like a dd() function in Laravel?

I need to get the request data but i cant get ip, fullUrl and others with all() method (this only print input values), but when i use "dd(request())" this show me all data (i need the data what is printed with dd method, but like a string to save, withour the exception who print this data). Im debbuging my app so i need to save every request data in a log file, something like:
\Log::debug($request)
So,
You can use:
\Log::debug($request->toString());
or alternatively you can use
\Log::debug((string) $request);
The Laravel Request object comes from Illuminate\Http\Request which extends Symfony\Component\HttpFoundation which exposes the following code:
public function __toString()
{
try {
$content = $this->getContent();
} catch (\LogicException $e) {
return trigger_error($e, E_USER_ERROR);
}
$cookieHeader = '';
$cookies = [];
foreach ($this->cookies as $k => $v) {
$cookies[] = $k.'='.$v;
}
if (!empty($cookies)) {
$cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
}
return
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
$this->headers.
$cookieHeader."\r\n".
$content;
}
__toString() is considered a magic method in PHP.
The __toString() method allows a class to decide how it will react
when it is treated like a string. For example, what echo $obj; will
print. This method must return a string, as otherwise a fatal
E_RECOVERABLE_ERROR level error is emitted.
You can read more about it in the official documentation.
I highly recommend to store just what you want from request data if you don't need all of them, however for both cases you can take a look at serialize and json_encode

How to Catch a "Trying to get property of non-object Error" in Laravel

How can I find the culprit of the following error in Laravel?
Trying to get property of a non-object Error
This is most probably coming from calling a method\property on a null object. So to fail early, you should use Model::firstOrFail(); or Model::findOrFail(ID);.
Other than that a null check can do it before you use, but it gets ugly if you have many null checks in your code.
try {} catch (\Exception $e) {} is also a way to catch an exception and handle it manually, but doing this in many places is again a lot of work.
What I do is use a ternary operation on the model before accessing properties of that model like so
$model = Model::find($id); $model ? $name = $model->name : null;
with this you can always be rest assured that a fatal throwable error would not be thrown if the model is not found. This also means you have to check if the variable name is not null before working with it like so if(!is_null($name) { //do your stuff here}

Laravel $request with variable returns null

I am writing an update methoda for my api. I neede to update requested fields.
So ı am trying to get only requested fields and update them. However, the code below returns me null even thoug I cast $fill to string.
foreach ($fillableFields as $fill){
$customerId->$fill = $request->get("$fill") ;
edit- 1
My code is like below ;
$fillableFields = array('lastname','firstname');
when I dd($fill) it returns me null .
You forgot to call the save() method to update your object :
foreach ($fillableFields as $fill){
$customerId->$fill = $request->get($fill);
$customerId->save();
}
Your method should be.
public function yourMethod(Request $request)
{
try {
foreach ($fillableFields as $fill){
$customerId->$fill = $request->get($fill) ;
}
}
} catch (\Exception $ex) {
}
}
Best way to get request parameters is provided at laravel's official documentation as below.
You can get request parameter based on your specific need.
By using below statment you can get only those perameter you have specified in only attribute as array eg : username, password.
$input = $request->only(['username', 'password']);
If you wantto get all fields excluding particular field than you can define as below with except parameter. eg: by using below it will allow to get all the fields except credit_card.
$input = $request->except('credit_card');
For more information on request parameter please refer official doc url : https://laravel.com/docs/5.4/requests

Laravel: resource not found exception

Say you have a simple resource route like this:
Route::resource('overview', 'OverviewController');
And hit routes which you know don't exist. For example:
/overview/sdflkjdsflkjsd
/overview/sdflkjdsflkjsd/edit
Which in my case throws Trying to get property of non-object error from my view (as no resource is found)
I looked into adding 'Regular Expression Parameter Constraints' from the docs, but it looks like these are not available for resource routes either (plus don't really fix the problem).
I'm looking for a way to throw a single exception for this kind of thing, which I can then handle once, rather than add logic to each action (or at least the show and edit actions).. if possible.
EDIT After looking around github, I found the exception in the Symphony repo here. Is there a way I can hook into it?
Since you're getting a Trying to get property of non-object error, I assume you're fetching the resource via YourModel::find();
I'd suggest you use YourModel::findOrFail() instead. Then, you'd be getting a specific type of exception called ModelNotFoundException. Just register an error handler for this.
For instance,
App::error(function(ModelNotFoundException $e)
{
return Response::make('Not Found', 404);
});
UPDATE: This would actually go into render() method inside the app/Exceptions/Handler.php file in Laravel 5.1, and of course the code would utilize the passed $e parameter instead.
public function render($request, Exception $e)
{
if ($e instanceof ModelNotFoundException)
{
return \Response::make('Not Found', 404);
}
return parent::render($request, $e);
}

Laravel 4: redirect if item doesn't exists, ModelNotFoundException doesn't work anyway I try it

I'm following Dayle Rees' book "Code Bright" tutorial on building a basic app with Laravel (Playstation Game Collection).
So far so good, the app is working but, following his advices at the end of the chapter, I'm doing my homeworks trying to improve it
So, this snippet is working fine for existing models but throws an error if the item doesn't exists:
public function edit(Game $game){
return View::make('/games/edit', compact('game'));
}
In other words, http://laravel/games/edit/1 shows the item with ID = 1, but http://laravel/games/edit/21456 throws an error since there's no item with that ID
Let's improve this behaviour, adapting some scripts found also here on StackOverflow (Laravel 4: using controller to redirect page if post does not exist - tried but failed so far):
use Illuminate\Database\Eloquent\ModelNotFoundException; // top of the page
...
public function edit(Game $game){
try {
$current = Game::findOrFail($game->id);
return View::make('/games/edit', compact('game'));
} catch(ModelNotFoundException $e) {
return Redirect::action('GamesController#index');
}
}
Well... nothing happens! I still have the error with no redirect to the action 'GamesController#index'... and please notice that I have no namespaces in my Controller
I tried almost anything:
Replace catch(ModelNotFoundException $e) with catch(Illuminate\Database\Eloquent\ModelNotFoundException $e): no way
put use Illuminate\Database\Eloquent\ModelNotFoundException; in Model instead of Controller
Return a simple return 'fail'; instead of return Redirect::action('GamesController#index'); to see if the problem lies there
Put almost everywhere this snippet suggested in Laravel documentation
App::error(function(ModelNotFoundException $e)
{
return Response::make('Not Found', 404);
});
Well, simply nothing happened: my error is still there
Wanna see it? Here are the first two items in the errors stack:
http://www.iwstudio.it/laravelerrors/01.png
http://www.iwstudio.it/laravelerrors/02.png
Please, can someone tell me what am I missing? This is driving me mad...
Thanks in advance!
Here are few of my solutions:
First Solution
The most straightforward fix to your problem will be to use ->find() instead of ->findOrFail().
public function edit(Game $game){
// Using find will return NULL if not found instead of throwing exception
$current = Game::find($game->id);
// If NOT NULL, show view, ELSE Redirect away
return $current ? View::make('/games/edit', compact('game')) : Redirect::action('GamesController#index');
}
Second solution
As I notice you may have been using model binding to your route, according to Laravel Route model binding:
Note: If a matching model instance is not found in the database, a 404 error will be thrown.
So somewhere where you define the model binding, you can add your closure to handle the error:
Route::model('game', 'Game', function()
{
return Redirect::action('GamesController#index');
});
Third Solution
In your screenshot, your App::error seems to work as the error says HttpNotFound Exception which is Laravel's way of saying 404 error. So the last solution is to write your redirect there, though this apply globally (so highly discouraged).

Resources