Undefined array key but with dd() works - php

I've done a query at Laravel and to check result content, I've used dd, but, for some reason, when I remove the dd(), it throws an exception sayint "Undefined array key 0". However, with dd DO find the key.
Code is this:
public function getFormatosArticulo(Articulo $articulo){
$formatoRaw = Formato::where('articulo_id', '=', $articulo->id)->get();
dd($formatoRaw[0]);
$formato = $formatoRaw[0];
return $formato;
}
And dd output is this:

I guess you are calling getFormatosArticulo function for multiple times, and passed not exists id into it. The get() function will always return a empty collection even if no data matched.
Can you test your function use code below and check if id does exists or not?
public function getFormatosArticulo(Articulo $articulo){
try {
$formatoRaw = Formato::where('articulo_id', '=', $articulo->id)->get();
$formato = $formatoRaw[0];
return $formato;
catch (Exception $e) {
dd($articulo->id); // i guess there is no articulo_id equal this in formato table.
}
}

The reason this happens is that dd stands for “dump and die” so your first iteration goes through but you don’t check the rest because you use die(). A solution to this can be as simple as:
public function getFormatosArticulo(Articulo $articulo) {
$formatoRaw = Formato::where('articulo_id', '=', $articulo->id)->get();
if ($formatoRaw) {
$formato = $formatoRaw[0];
return $formato;
}
}
Since you are only interested for the [0] position though a similar approach would be:
public function getFormatosArticulo(Articulo $articulo) {
$formatoRaw = Formato::where('articulo_id', '=', $articulo->id)->first();
if ($formatoRaw) {
return $formatoRaw;
}
}

Related

App\Models\ must return a relationship instance

I am trying to run some dynamic method calls based on the value of a database field. Some context: I have a model Anniversary and I want to display all upcoming anniversaries within the next x days. An anniversary has a date and a frequency. For example, monthly, quarterly, etc. Based on the frequency, I want to check for each anniversary if it is upcoming.
Here is my code so far:
$anniversaries = auth()->user()->anniversaries()->get();
$test = $anniversaries->filter(function ($anniversary) {
$method = Str::of($anniversary->frequency)->camel();
return ${$anniversary->$method}() == true;
});
dd($test);
The above works, when in the actual method I dd() something. But when returning true or false, I get the error:
App\Models\Anniversary::monthly must return a relationship instance
And in my model I just have a few methods like below, for testing:
public function monthly()
{
return true;
}
public function quarterly()
{
return false;
}
My only question is, I want to understand why I am getting this error and ofcourse any pointers in the right direction to get what I want to work. Thanks!
The following line creates an Illuminate\Support\Str object instead of a string. This causes the Method name must be a string error.
$method = Str::of($anniversary->frequency)->camel();
You can fix this by manually casting it to a string and invoking it directly:
$test = $anniversaries->filter(function ($anniversary) {
$method = (string) (Str::of($anniversary->frequency)->camel());
return $anniversary->$method() == true;
});
Throwing in my 2 cents for this as well. The Str::of(), which are "Fluent Strings" added in Laravel 7.x return an instance of Stringable:
https://laravel.com/api/8.x/Illuminate/Support/Stringable.html
For example:
dd(Str::of('monthly')->camel());
Illuminate\Support\Stringable {#3444
value: "monthly"
}
To get the value of this, as a string and not an object, you can cast it (as shown in MaartenDev's answer), or call the __toString() method:
dd(Str::of('monthly')->camel()->__toString());
"monthly"
In your code example, that would simply be:
$method = Str::of($anniversary->frequency)->camel()->__toString();
return $anniversary->{$method}() == true;
Alternatively, you can just use the Str::camel() function to bypass this Stringable class:
$method = Str::camel($anniversary->frequency);
return $anniversary->{$method}() == true;
https://laravel.com/docs/8.x/helpers#method-camel-case
Hope that helps clear up some confusion 😄
you have issue in this part ${$anniversary->$method}(). if you access a function like property laravel models thinks its relation function.
so replace with $anniversary->{$method}()
try this one
$anniversaries = auth()->user()->anniversaries()->get();
$test = $anniversaries->filter(function ($anniversary) {
$method = Str::of($anniversary->frequency)->camel();
return $anniversary->{$method}() == true;
});
dd($test);

Passing a variable to a ->each() function making the variable always = 0 php

One of the routes I'm making for my API in laravel requires me to pass a variable to a ->each() function.
This can be seen below:
public function by_location($zone_id)
{
$zone = Zone::where('id', $zone_id)->get()[0];
error_log($zone->id);
$exhibitors = Exhibitor::where('zone_id', $zone_id)->get();
$exhibitors->each(function($exhibitor, $zone)
{
error_log($zone->id);
$exhibitor['zone_info'] = $zone;
});
return response()->json($exhibitors);
}
This first error_log outputs '2', but with the second I get 'Trying to get property 'id' of non-object'.
Any help is apprecited!
You probably want to use $zone which you selected from database on first line.
Also if you want to change value of item you are iterating you have to use ->map() instead of ->each()
I changed ->get()[0] to ->first(). Never use ->get()[0]
public function by_location($zone_id)
{
$zone = Zone::where('id', $zone_id)->first();
error_log($zone->id);
$exhibitors = Exhibitor::where('zone_id', $zone_id)->get();
$exhibitors->map(function($exhibitor) use ($zone){
error_log($zone->id);
$exhibitor['zone_info'] = $zone;
return $exhibitor;
});
return response()->json($exhibitors);
}

count() parameter must be an array or an object that implements countable in laravel

This is code here:
protected function credentials(Request $request)
{
$admin=admin::where('email',$request->email)->first();
if(count($admin))
{
if($admin->status==0){
return ['email'=>'inactive','password'=>'You are not an active person, Please contact to admin'];
}
else{
return ['email'=>$request->email,'password'=>$request->password,'status'=>1];
}
}
return $request->only($this->username(), 'password');
}
When i run the code this error become:
"count(): Parameter must be an array or an object that implements Countable"
It happens because of in PHP 7.2 NULL in count() return Warning.
You can try to change
count($admin)
to
count((is_countable($admin)?$admin:[]))
This is my solution:
count(array($variable));
Note that here, When you use the count() method, there should be countable element, like an array or object that implement ArrayAccess.
Admin::where('email',$request->email)->first();
But the first() method give you single element, not a collection or array. The get() method returns you countable a collection with found elements
Instead of using count you can directly check variable itself is it defined or null
if($admin){
// do something here
}
or you can use is_null() method
if(!is_null($admin)){
// do something here
}
$admin variable is neither array nor object that implements countable. When you use first() the result will be a model object if record is found else it will be null. For this condition you can use:
if (!empty($admin)) {
//
}
Just replace if (count($admin)) with if (!empty($admin)).
And when you use get() method to get multiple records you can check by:
if ($admins->count() > 0) {
//
}
You should check if it is null instead of count, because you ask for one result with first()
just this
if($admin)
will do it.
if you use return a collection using ->get() then you can check $admin->count().
You can cast the variable to an array:
count((array)$variable);
If it's null then it will become an empty array.
Well,
$admin=Admin::where('email',$request->email)->first();
//It will always return an **object**.
And make sure you included Admin model in your controller like as.
Use App\Admin;
at the same time check that you will have to mention which field of table needs to be fillable like in your model such as
protected $fillable = [
'first_name',
'last_name'
];
whatever data you will going to save in your database.
and then check object is null or not
I mean is.
if($admin && $admin!==null){
//do whatver you want to do.
}
$admin = null;
var_dump(count($admin));
output: Warning: count(): Parameter must be an array or an object that implements Countable in … on line 12 // as of PHP 7.2
if condition should be like:
if(isset($admin) && count($admin))
Use isset($admin->id) instead of count($admin)
Try this :
protected function credentials(Request $request)
{
$admin=admin::where('email',$request->email)->first();
if(isset($admin->id)))
{
if($admin->status==0){
return ['email'=>'inactive','password'=>'You are not an active person, Please contact to admin'];
}
else{
return ['email'=>$request->email,'password'=>$request->password,'status'=>1];
}
}
return $request->only($this->username(), 'password');
}
In my case count was 1 even when I got [] from api
so I had to put it in try catch
try{
$propertyId = arr[0].propertyId;
}catch(\Exception $e) {
return response()->json(['success' => 'false']);
}
add this your controler this code:
$user = User::where('email',$request->email)->first();
if ($user){
return redirect()->back()->with('errors','We cant find a user with that e-mail address.');
}else{
$user->password = bcrypt($request->new_password);
$user->update();
return redirect()->back()->with('success','Success');
}

Handle Undefined Offset warning in PHP, when value at the index is an object

I have a code like this:
class PlayerList{
public static $player_list= array();
//other functions
function getPlayer($playerNumber){
if(isset((self::$player_list[$playerNumber])))
return self::$player_list[$playerNumber];
else
return NULL;
}
This function getPlayer($playerNumber) should return the player object in the static array $player_list indexed using the given $playerNumber. It works when the index exists else throws an undefined offset. The index is an important attribute of objects of Player class, so re-ordering the array is out of question.
Now, in the calling part:
$players=new PlayerList();
$playerNumber=readline("\n\nEnter player number:");
$player=$players->getPlayer($playerNumber);
if(//valid player){
//code
}
else{
//code
}
How do i check if the indexed player exists or not,and if not, return null, in the getPlayer function itself, and prevent PHP from giving undefined offset notice?
Well, first of all, you have a typo in your code assuming a variable called $playereNumber. If this is not the issue, you can try following code for your class.
class PlayerList
{
public static $playerList = [];
function getPlayer($index)
{
return isset(static::$playerList[$index]) ? static::$playerList[$index] : null;
}
}
You should also consider not making the $playerList static in case you will be loading them from some database later.
Try this code :
class PlayerList
{
public static $playerList = [];
function getPlayer($index)
{
return isset(static::$playerList[$index]) ? static::$playerList[$index] : null;
}
}
$players=new PlayerList();
$playerNumber=readline("\n\nEnter player number:");
$player=$players->getPlayer($playerNumber);
if($player){
//player exist
}
else{
//player is null
}
As you are returning NULL when you cannot find a player, simply test for NULL using isset()
$player=$players->getPlayer($playerNumber);
if ( isset($player) ) {
// Player exists
}else{
// Player Does NOT exists
}
In fact you could probably get away with a simple
$player=$players->getPlayer($playerNumber);
if ( $player ) {
// Player exists
}else{
// Player Does NOT exists
}

Recursive function in php storing results without using static

I wrote the following recursive function to keep looping through result looking for $result->pages->next and calling out to curl fetching the next page and aggregating the results. Finally it returns all results as a single object.
private function pager($result) {
static $all_results;
if(isset($result->pages->next) && !empty($result->pages->next)) {
$all_results[] = $this->get_curl_request($result->pages->next);
$this->pager(end($all_results));
} else {
return $all_results;
}
}
However I really don't like using static and it feels poorly implemented and a source of technical debt. What is a more elegant way to do this?
Update
Being called with:
return $this->pager($this->get_curl_request("https://api/request/here"));
Open to changing how it is called.
Try putting $all_result as second parameter like this and add return for this line: $this->pager(end($all_results), $all_results);
Code
private function pager($result, $all_results) {
if(isset($result->pages->next) && !empty($result->pages->next)) {
$all_results[] = $this->get_curl_request($result->pages->next);
return $this->pager(end($all_results), $all_results);
} else {
return $all_results;
}
}
The above code function will return the last updated array $all_results.
Example of use:
$pager_array = $this->pager($result, array());

Categories