assertJson and assertSee show call to a null member error - laravel

I trying to develop a test for my APIs,
This is my code:
public function testFirstAPI()
{
$user = \User::find(1);
$r = $this
->actingAs($user)
->json('put', route('updateUser'),['lock' => 'true']);
$r->assertResponseStatus(200)->seeJson(['success' => true]);
}
this test will work and when I use $r->dump() I can found the success in the response.
but I don't know why seeJson show this error:
Symfony\Component\Debug\Exception\FatalErrorException]
Call to a member function assertJson() on null

This is because you are chaining assertResponseStatus() first and it does not return a fluent object.
A solution would be to put it as the last assertion in the chain:
public function testFirstAPI()
{
$user = \User::find(1);
$this->actingAs($user)
->json('put', route('updateUser'), ['lock' => 'true'])
->seeJson(['success' => true])
->assertResponseStatus(200)
}

Related

Call to a member function move() on null when update in laravel

I got this errror when trying to update data. If I update the image there's no error, but if I'm not it showing Call to a member function move() on null
This is my code:
public function update($id, Request $request)
{
$change = Profile::findorfail($id);
$before = $change->foto_profil;
$profile = [
'fullname' => $request['fullname'],
'phone' => $request['phone'],
'ttl' => $request['ttl'],
'foto_profil' => $before
];
$request->foto_profil->move(public_path().'/image', $before);
$change->update($profile);
return redirect('/profil');
}
You may determine if a file is present on the request using the hasFile() method :
if($request->hasFile('foto_profil')){
$request->foto_profil->move(public_path().'/image', $before);
}
See the documentation here
just add validation if photo exists in request
if($request->foto_profil) {
$request->foto_profil->move(public_path().'/image', $before);
}

Laravel model function best prickets

im new in Laravel , I have an issue as below
I make in category model query to check is category is exist or not
as below
public function scopeIsExist($query ,$id)
{
return $query->where(['deleted' => 1, 'id' => $id])->orderBy('id', 'DESC')->first();
}
and my controller is
public function edit($id)
{
$dataView['category'] = Category::IsExist($id);
if(!$dataView['category'])
{
return view('layouts.error');
}else{
$dataView['title'] = 'name';
$dataView['allCategories'] = Category::Allcategories()->get();
return view('dashboard.category.edit')->with($dataView);
}
}
my problem is when I use method isEXIST if id not found it not redirect to error page but ween i remove ISEXIST AND replace it as below
$dataView['category'] = Category::where(['deleted' => 1, 'id' => $id])->orderBy('id', 'DESC')->first();
it work well .
can any one help me
That's because local scope should return an instance of \Illuminate\Database\Eloquent\Builder. You should remove the first() in the scope and put it in the controller.
Redefine your scope like so:
public function scopeIsExist($query ,$id)
{
return $query->where(['deleted' => 1, 'id' => $id])->orderBy('id', 'DESC');
}
In your controller edit method:
$dataView['category'] = Category::IsExist($id)->first();
You can have a look to the doc for local scopes https://laravel.com/docs/8.x/eloquent#local-scopes

How to avoid error when using Eloquent's toArray when getting null result

l am getting start at a new laravel project with 5.7, but one problem, when l use first() to fetch data, and if data is not exist, it will return null, and then execute toArray() will throw a PHP error. So l use follow code to reslove it.
$user_model = \App\Model\User::where('id', $id);
if ($select) {
$user_model->select(explode(',', $select));
}
$user_data = $user_model->first();
$user_data = $user_data ?? $user_data->toArray();
So is there any better way?
Any one of the following will work, each providing their own way of dealing with a null result:
1. optional helper:
The optional function accepts any argument and allows you to access
properties or call methods on that object. If the given object is null,
properties and methods will return null instead of causing an error.
$user_data = optional($user_model->first())->toArray();
2. firstOr():
Execute the query and get the first result or call a callback.
$data = User::where('id', $id)->when(!is_null($select), function ($query) use ($select) {
return $query->select(explode(',', $select));
})->firstOr(function () {
return ['message' => 'No results'];
});
3. rescue helper:
The rescue function executes the given Closure and catches any exceptions that occur during its execution. All exceptions that are caught will be sent to your exception handler's report method; however, the request will continue processing.
$data = rescue(function () use ($select) {
\App\Model\User::where('id', $id);
if ($select) {
$user_model->select(explode(',', $select));
}
return $user_model->first()->toArray();
});
4. try catch:
try {
$user_model = \App\Model\User::where('id', $id);
if ($select) {
$user_model->select(explode(',', $select));
}
$user_data = $user_model->first();
$user_data = $user_data ?? $user_data->toArray();
} catch(\Exception $e) {
// handle the exception...
}
Laravel provides a firstOrFail method which throws an 404 Exception by default.
$user_data = $user_model->firstOrFail(); // If not found an exception is thrown and will be handled by default ExceptionHandler which displays a 404 error page.
// if found, cast the User to array
$user_data = $user_data->toArray();

Laravel ORM relationship returns error when value not present in DB

I have an issue with querying relationships.
I am querying relations between Projects, Companies and Products. However, whenever a Project ID is not present in the database an fatal exception is trown:
Call to a member function companies() on a non-object
public function index($i) {
return $this->returnTop($i, Array(
'projectid' => 5,
'products' => Array(1, 2, 3)
)
);
}
public function returnTop($count = 6, $args = Array()) {
$companies = Project::find($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
}
Now, I know that project id 5 is not present in the DB, and this is likely to be the cause of this error, but I want to return a message instead of the application throwing a fatal error....
Any ideas?
Just check if find() returns null. Something like this:
$project = Project::find($args['projectid']);
if(is_null($project)){
return Response::json(['message' => 'Project not found']);
}
$companies = $project->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
An alternative would be findOrFail which throws a ModelNotFoundException. You could handle the exception globally or catch it inside the controller:
try {
$companies = Project::findOrFail($args['projectid'])->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e){
return Response::json(['message' => 'Project not found']);
}
You first have to test whether the returned object is actually not null. Blindly assuming a database query succeeds is waiting for sh*t to hit the fan.
public function returnTop($count = 6, $args = Array()) {
$project = Project::find($args['projectid']);
if($project) {
$companies = $project->companies()->whereHas('products', function($q) use($args) {
$q->whereIn('products.id', $args['products']);
})->with('products')->limit($count)->get();
return Response::json($companies);
}
else {
return; // .. your error or whatever
}
}
Also the "call to a member function on a non-object" is quite specific, it tells you that a method (member function) could not be called due to the fact that you are trying to call it on a non-object.

Laravel 4 Framework - Query scope not working

Im a big 'ol newbie at Laravel, and im trying to do a query scope but it doesnt seem to be working, i keep getting this error
Argument 1 passed to Letters::scopeForUser() must be an instance of User
My user IS logged in, but it still doesnt seem to be working.
This is my Letters model
<?php
class Letters extends Eloquent {
protected $table = 'letters';
public function scopeForUser(User $u)
{
return $query->where('userid', '=', $u->id);
}
}
and in my controller i have the following
Route::get('myletters', array(
'before' => 'auth|userdetail',
function()
{
// Grab the letters, if any, for this user
$letters = Letters::forUser(Auth::user())->get();
$data = [
'letters' => $letters
];
return View::make('myletters', $data);
}
));
Any help would be greatly appreciated.
Cheers
You should pass a variable $query as the first argument to your method in the Model. For example:
public function scopeForUser($query, User $u)
{
return $query->where('userid', '=', $u->id);
}
The first argument doesn't necessarily need to be $query, but it should be the same variable that you are using inside the scope method ($query in this case).

Resources