Undefined property: Illuminate\Support\Collection::$election_name in view - laravel-5

In the controller, I store some data in an array.Then I want to send it in myelectionlist.blade.php
$my_election=[];
$i=0;
foreach ($election_list as $election_list)
{
$my_election[$i]=DB::table('election')
->where('id','=',$election_list->election_id)
->get();
$i++;
}
return view::make('myelectionlist')->with('election_list',$my_election);
I check with
return $my_election
It works fine. But In myelectionlist.blade.php when I write
#for($i=0;$i<sizeof($election_list);$i++)
{{$election_list[$i]->election_name}}
#endfor
It does not work.
Undefined property: Illuminate\Support\Collection::$election_name
happens, How to solve the problem?

There's a combination of problems that I would fix in order to bring clarity to your code and explain to you the problem. First of all in your code you have:
foreach ($election_list as $election_list)
I'll rename the variable for you to see:
foreach ($foo as $foo)
So what this does is that inside the foreach loop you will get all the values one by one, like expected but every time you store it to the initial variable. And once you are done with the foreach or break out of it earlier the $election_list will have the last used value. It might have unexpected results if you're trying to use the same $election_list later again. So I would suggest to use a differet variable names perhaps like $election_list as $election
Next, it's a little bit unclear why you would track the $index of the new elements by yourself. Instead you could just push into the array like this:
$my_election[] = $newObj
Actual error message:
Now for the actual error message: ->get() returns a Collection. So in the end you have an array full of Collections. So inside the for loop when you do $election_list[$i] - this will actually be a Collection object instead of the Model and thus the exception.
->get() will always get you the collection. For example with methods like ->first() and find/findOrFail you would get a single model. These functions might also be more appropriate to use since we are requesting with and id anyway.
Additionally, if this question is not a simplified version of your code then what I think you should actually do inside the controller:
$my_election = DB::table('election')
->whereIn('id', $election_list->pluck('election_id')) // pluck will give all the id's
->get();
This way you have a Collection of models assigned to $my_election.

Related

Error Call to a member function where() on array Laravel

I want to do filtering from the data that I display, but there is a problem when I add where to my data.
the plan in the future I want to add if isset $request name, date and others. but was constrained at this one point.
Thank you for helping to answer in advance
$matchs =Matchs::where('type', 'sparring')->where('status','Pending')->whereNull('deleted_at')->get()->toArray();
$data=[];
foreach ($matchs as $key) {
$lawan = Matchs::where('id', $key['id'])->first()->ToArray();
$pertandingan = Sparring::where('match_id', $key['id'])->first()->ToArray();
$dua_arah = MatchTwoTeam::where('match_id', $key['id'])->first()->ToArray();
$tim = Team::where('id', $dua_arah['home_team'])->first()->ToArray();
$transfer['name']=$tim['name'];
$transfer['city']=$lawan['city'];
$transfer['field_cost']=$pertandingan['field_cost'];
$transfer['referee_cost']=$pertandingan['referee_cost'];
$transfer['logo_path']=$tim['logo_path'];
$transfer['nama_lapangan']=$lawan['nama_lapangan'];
$transfer['date']=$lawan['date'];
array_push($data,$transfer);
array_push($data,$pertandingan);
}
$data->where('name', 'LIKE', '%'.'football'.'%')->get()->toArray();
$data = array_search('football', array_column($data, 'name'));
$tittle="Sparring";
return view('mode.sparring',[
'tittle' => $tittle,
'data' => $data,
]);
You are trying to call where in an array which is not possible.
As you can see in the first line of your code you are calling where method in your model class. Like Matchs::where('type', 'sparring'), this is possible because Matchs is a Model class.
Now you can run where even if you are using array. You can convert that day in collection and then use array on that collection.
As below:
collect($data)->where('name', 'football')->toArray();
Here collect() will convert the $data array to collectio and then run the where() method in collectio then toArray() will change it back to array. But unfortunately there is no like operator possible in collection class. See the list of available method in Laravel collection here: https://laravel.com/docs/8.x/collections#available-methods
There is a way to do what you are trying to do. As far as I understand you want to filter the Matches where the Team name has footbal in it. You can do it like this:
Matchs::where('type', 'sparring')
->where('status','Pending')
->whereNull('deleted_at')
->whereHas('team', function($team) {
return $team->where('name', 'LIKE', '%'.'football'.'%')
})
->get()
->toArray();
So, here we can get the only those Mathes that has the Team that has the name contains football.
Few suggestion for you as seems you are new in Laravel:
Model name should be singular instead of plural, so the model class Matchs should be Match. Your name for team's model is Team is correct.
Avoid using toArray() because you won't need it. When you call get() it will return object of collection which more readable and powerful then array in most cases.
The code I suggested to use the like using whereHas will only work if you have propery defined your team relation in your Matchs class. So, defining your relationships in model is also important. If you do so, you don't even need the for loop and all those where in other model in that loop. You can do it in one query with all the relationships.

How to apply an operation/functionality on one column during getting data of a table in Laravel Controller?

I want to get all the data of today's Date, but during getting it I want to apply an operation on the data of one column only NOT others. This operation is from another function.
$data = Net::whereDate('created_at', Carbon::today())->get();
I have two options:
During getting data, call to that function on the specific column
After getting data, put a loop and then apply that operation and save data into new object
In this table, there is a column called profit, and I want to encode this profit into alphabets by calling encode_code() function remaining the other data as it is.
I don't know how I can do this, please help me if anyone knows.
You can use a foreach loop to get each object from the collection and for each of those object,call the desired function.
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $key => $dat)
{
$data[$key]->profit = encode_code($dat->profit);
}
I think you should call the function and turn it like this
I just didn't know what you wanted to do, so this is my best
$data = Net::whereDate('created_at', Carbon::today())->get();
foreach($data as $i => $d){
$data[$i]->profit = encode_codeļ¼ˆ$d->profit);
}
Of course you could loop through your result and encode each row, but this would prevent you from reusing this code.
Instead you could put that encode function directly into the model, so that you can reuse it everywhere:
public function getEncodedProfit() {
return encode_code($this->profit);
}
Now you can just use this function everywhere in your controllers or views like that:
echo $net->getEncodedProfit();

Eloquent resulting single search result as array not collection

I have some instances where a eloquent is resulting an single array not a collection. Although dd shows it as a collection with a single entry.
For example I have a query in a controller:
$pg = Page::with('getPanels')->where('slug',$slug)->get();
This will return a single result and works fine, so I pass this to a blade template. My complete function is
$pg = Page::with('getPanels')->where('slug',$slug)->get();
return view('front.page',['pg' => $pg]);
As soon as he template is brought in it will fall over at
if (!is_null($pg->headImage))
{$img = asset('images/pages')."/".$pg->headImage;}
and I will get
Property [headImage] does not exist on this collection instance.
If I change the line to
if (!is_null($pg[0]['headImage']))
it will continue OK. This is of course a pain as I would much rather use $pg->headImage.
Can someone enlighten me please?
I have sorted this and I hope it will help other people.
If I use
$pg = Page::with('getPanels')->where('slug',$slug)->first();
it will be just one result (naturally) and therefore
$pg->headImage
will fail as it wants
$pg[0]['headImage']
but if I change the eloquent instead of get(0 to first() (still just one result)
$pg = Page::with('getPanels')->where('slug',$slug)->first();
I can use $pg->headImage or what field I want.

Laravel Eloquent: count($result) vs $result->count()

I'm a bit new to this, and was originally trying to check if my model was returning results with isEmpty(), but thought I'd try count() instead, then I came across the following:
I've got the following code, which returns data from my model:
$results = Game::where('code', '=', $code)->with('genre', 'creator')
And whether I use first() or get() combined with count(result) or $results->count() I get different values, and I'm not sure why.
when using ->first()
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
dd($results->count()) = 1 // What I'd expect the query to return
when using ->first()
dd(count($results)) = "count(): Parameter must be an array or an object that implements Countable"
when using ->get()
dd(count($results)) = 1
I don't understand 1) why when using first, the count is the same as every row in the db. 2) Why count() can't be used with first().
Is anyone able to shed some light as to why I can't use count on first as I'd like to?
Update:
I'm also not able to use ->isEmpty() with ->first() but can with ->get()...?
When I try using it with first, I get Illuminate\Database\Query\Builder::isEmpty does not exist.
Disclaimer: I'm not sure why your database count and your results count aren't the same, however I can shed some light on the different types of count.
Game::where('code', '=', $code)->count();
This is being called on a query builder instance. It is run on the database query, without selecting all the rows. Check out the title Aggregates here: https://laravel.com/docs/5.7/queries
Game::where('code', '=', $code)->get()->count();
As soon as your use get() laravel selects the rows, boots them all as models, and creates a collection. This count is on the collection (a bit like an array) so just gets the number that are returned (i.e. if they are paginated or anything like that it will just get that amount). Check out Count here.
Game::where('code', '=', $code)->first()->count();
This is being run on the first returned model... unless you've written it, a default laravel model won't have a count() method.
count($results)
Finally, count() when not a class method is just the default php function that returns the length of an array or other object (documentation).
First of all,
get() returns collection of objects while first() returns modal object of query.
$results = Game::where('code', '=', $code)->with('genre', 'creator')
dd($results->count()) = 11930 // Number of rows in the db
when using ->get()
$results = Game::where('code', '=', $code)->with('genre', 'creator')->get()
dd($results->count()) = 1
because it has collection, which contains numbers of objects of database data. As ->count getting only one collection so it returns 1.

To Array or Not To Array?

In my model I get data using something like:
$this->all();
This is then returned to my controller which makes a view:
return View::make('myView')
->with('data', $this->myModel->getAll());
My question is, what's best practice, should the model return eloquent object or an array? By calling ->toArray()?
Short answer is to leave as objects. It seems silly to me to convert to arrays when the objects can be used in the view.
Consider if you might need to foreach through a model's relationships - using an array you either don't have this or have to preload it (even if you won't always have to use it), using an object, you can choose to use the relationship if you want to.
Now, I'm aware this is related to your previous question regarding passing arrays vs. object to the view, but that is a different question entirely. In that question you're basically saying "sometimes I have one object and sometimes I have a collection of objects, how do i handle this in the view". To which my answer would be that you sure ensure the view always sees a collection (or array or whatever), but never to actually convert an object to an array.
In that situation, in the case where you only get one object, just wrap that object in a collection (or array) before it goes to the view and there you go - normalised data done easily.
To wrap your result in a collection
There are many ways of doing this which depend on how you're getting the data in the first place. If you're doing your own Eloquent calls then the simplest solution is to always use ->get() rather than sometimes using ->find() or ->first(). If you use ->get() even in times you expect a single result, it'll return a single result wrapped in a collection already.
However, if you're provided with this someties-object-sometimes-array then you'll have to manually do it. Again this has two different but very similar tehcniques which depends on whether the data is compatible with Eloquent and Collection or whether it's more raw PHP objects and arrays.
Eloquent-compatible
if ($data instanceof \Illuminate\Databse\Eloquent\Model) {
$data = new \Illuminate\Database\Eloquent\Collection($data);
}
Standard objects and arrays
if (!is_array($object)) {
$data = array($data);
}
It's really as simple as that.
In my opinion, the cleaner, elegant way is always returning an object.
In a model I would do something like this
class Employee extends Eloquent {
protected $table = 'employees';
}
In the controller
public function index(){
$employees= Employee::get();
return View::make('index')->with('employees', $employees);
}
In the view:
#foreach($employees as $employee)
{{ $employee->name }}
#endforeach
Simply, it depends what do you want to do with returned data. In most cases, we are traversing returned array in a view (with blade), and appending it to some HTML list. I had some issues with passed data to view and unit testing.
Simply, test is not accepting object, so I explicitly had to pass array.

Resources