laravel ->get() not returning relations properly - arrays

I have a conditional query that works in my index controller that should return eloquent relationships but does not always return an accessible array index:
$customers = Customer::with('orders', 'regions')->orderBy('created_at', 'desc')->whereHas('regions', function($query)
{
$user_id = Auth::user()->id;
$current_user = User::with('roles')->where('id', '=', $user_id)->latest()->first();
$role_name = $current_user->roles[0]->name;
if($role_name == 'admin_master'){$query->whereIn('region', array(11, 7));}
}
)->get();
The problem is the related array is not always accessible eg order[1] and displays oddly when I dd($customers);
#relations: array:5 [▼
"orders" => Collection {#442 ▼
#items: array:2 [▼
0 => Order {#446 ▶}
1 => Order {#447 …25}
]
}

For future users, the get method gets the results as a collection. You can chain the toArray() method on it to convert it into an array.
So it will be something like $query->get()->toArray()

Related

How to order an array by bool values in laravel livewire

I have an array, I want to order that array by "is_available" key, (true first)
I'm using laravel 8 and a livewire component
0 => array:12 [▼
"id" => 1
"name" => "치킨 ~The Chicken~"
"is_available" => true
"nearest_customer_distance" => 4905.4423678942
"customers" => array:26 [▶]
]
1 => array:12 [▼
"id" => 2
"name" => "混ぜるな危険"
"is_available" => false
"customers" => array:10 [▶]
]
2 => array:12 [▼
"id" => 3
"name" => "Oh! Bánh mì"
"is_available" => true
"customers" => array:8 [▶]
]
3 => array:12 [▼
"id" => 5
"name" => "CHIJIMI DEVIL"
"is_available" => false
"customers" => array:44 [▶]
]
]
I'm trying this
$newFranchiseList = $this->getFranchiseListActualPage();
$finalFranchiseList = array_merge($this->franchiseList, $newFranchiseList);
$finalFranchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse();
$this->franchiseList = $finalFranchiseList->toArray();
but I get the order by ID in my view, this is my view
#forelse($franchiseList as $franchise)
#if($franchise['is_available'])
{{$franchise['name']}}
IS AVAILABLE
#else
{{$franchise['name']}}
NOT AVAILABLE
#endif
#empty
#endforelse
if I do a dump($this->franchiseList) the list is shown with the order of is_available!
note: $this->franchiseList is never used in the component, the only line to be used is the last one, if I don't use this line, the list is empty
component data collection process
first, in javascript call a livewire listener
window.livewire.emit('franchises:selectedCoords', JSON.stringify(selectedCoords));
then that is received by the component
public $selectedLatitude,
$selectedLongitude,
$perPage = 20,
$franchiseList = [],
$page = 1,
$totalFranchises = 0,
$isLoaded = false;
protected $listeners = [
'franchises:selectedCoords' => 'getCoords'
];
public function render()
{
return view('livewire.franchise-list');
}
public function getCoords($selectedCoords)
{
if ($selectedCoords) {
if (!empty($this->franchiseList)) {
$this->clearList();
}
$this->selectedLatitude = json_decode($selectedCoords, true)['lat'];
$this->selectedLongitude = json_decode($selectedCoords, true)['lng'];
}
$this->getFranchiseList();
}
public function getFranchiseList()
{
if ($this->selectedLatitude && $this->selectedLongitude) {
if (!$this->allFranchisesAreLoaded())
{
$newFranchiseList = $this->getFranchiseListActualPage();
$finalFranchiseList = array_merge($this->franchiseList, $newFranchiseList);
$this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->toArray();
}
$this->isLoaded = true;
}
}
remember that $this->franchiseList is never overwritten, that is, it is only used once, in the line $this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->toArray (); and if it is not done, it ends up being an empty array, so there is no other $this->franchiseList with the order shown by the blade view
Livewire will on each request serialize the public properties, so that it can be sent to the frontend and stored in JavaScript.
Now here's the kicker: JavaScript will do its own internal sorting on objects, which you can't prevent. So to work around that, you have to re-key your array after you sort it, so that the keys are now in ascending order of what you sorted it to.
Basically, all you need to do before you call ->toArray(), is to call ->values() on it, thereby grabbing the values in the order they were, and PHP will assign it new keys starting from 0.
$this->franchiseList = collect($finalFranchiseList)->sortBy('is_available')->reverse()->values()->toArray();
For example, a object like this in JavaScript,
{
1: 'foo',
0: 'bar',
}
Will be internally sorted by JavaScript like this
{
0: 'bar',
1: 'foo',
}
And you can't change that. That's why you need to re-key it.

Fetch data from database where logged in user id exist in an column that stores ids as an array Laravel 8

I want to get the rows in a database where logged in user exists. Here is my structure
Table = Meetings
Column = Participants (stores an array of users eg.["1","2","3"]);
Auth()->id() = "1"
I want a query that will fetch rows if Auth()->id() exist in participants which stores an array of User id.
here is my code:
$meetings = Meeting::join('venues', 'meetings.meeting_venue', '=', 'venues.id')
->join('organizers','meetings.meeting_organizer','=','organizers.id')
->join('users', 'meetings.user_id','=','users.id')
->where('meetings.participants', '=', auth()->id())
->get(['meetings.*', 'venues.venue_name', 'organizers.organizer_name','users.name', ]);
Here is my participants column from the database:
array:1 [▼
0 => array:1 [▼
"participants" => array:3 [▼
0 => "52"
1 => "56"
2 => "57"
]
]
]
$meetings = DB::table('meetings')->whereJsonContains('meetings.participants', auth()->id())->get()->toArray();
dump returns empty array.
found a way around it I assigned auth()->id() to a variable then added double quote in the query. Below is how I did it
$uid = auth()->id();
-> whereJsonContains('meetings.participants', "$uid");
this works fine
You can use a trick, here it is:
$meetings = Meeting::join('venues', 'meetings.meeting_venue', '=', 'venues.id')
->join('organizers','meetings.meeting_organizer','=','organizers.id')
->join('users', 'meetings.user_id','=','users.id')
->where('meetings.participants', 'like', "%\"{auth()->id()}\"%")
->get(['meetings.*', 'venues.venue_name', 'organizers.organizer_name','users.name']);
or You can use whereJsonContains(), like so:
$meetings = Meeting::join('venues', 'meetings.meeting_venue', '=', 'venues.id')
->join('organizers','meetings.meeting_organizer','=','organizers.id')
->join('users', 'meetings.user_id','=','users.id')
-> whereJsonContains('meetings.participants', "'".auth()->id()."'")
->get(['meetings.*', 'venues.venue_name', 'organizers.organizer_name','users.name']);
Hope this helps you. Greetings

How can I check if a value exists in my Object PersistantCollection?

My object "fields":
array:4 [▼
0 => Fields {#10900 ▶}
1 => Fields {#11222 ▶}
2 => Fields {#11230 ▼
-id: 8
-name: "Tier"
-uuid: "5f60107fe4"
-productgroup: PersistentCollection {#11231 ▶}
-options: PersistentCollection {#11233 ▶}
-template: PersistentCollection {#11235 ▼
-snapshot: []
-owner: Fields {#11230}
-association: array:20 [ …20]
-em: EntityManager {#4288 …11}
-backRefFieldName: "fields"
-typeClass: ClassMetadata {#7714 …}
-isDirty: false
#collection: ArrayCollection {#11236 ▼
-elements: []
}
#initialized: true
}
-type: Type {#11237 ▶}
-formatstring: ""
}
3 => Fields {#11511 ▶}
]
I want to find out if a certain "templateId" exists in "fields":
foreach ($fields as $field) {
$templateId = $field->getTemplate();
$result = property_exists($templateId, 3);
}
The result is "false", even if I expect it to be true.
Entity field list: https://pastebin.com/zcuFi1dE
Template: https://pastebin.com/mVkKFwJr
First of all,
$templateId = $field->getTemplate();
return an ArrayCollection of Template (By the way you should rename your property Templates)
I believe what you want to do is check if a Template is in the array template of Fields.
So there are two proper ways to do it :
Using the contains method from Doctrine\Common\Collections\ArrayCollection
Compare an object to another
//First get the proper Template object instead of the id
$template = $entityManager->getRepository(Template::class)->find($templateId);
$templateArray = $field->getTemplate();
//return the boolean you want
$templateArray->contains($template);
Compare indexes/keys :
$templateArray = $field->getTemplate();
//return the boolean you want
$templateArray->containsKey($templateId);
But in the case you want to do the same thing but with another property than the id you can loop through your array :
Compare other attribute
//In our case, name for example
$hasCustomAttribute=false;
foreach($field->getTemplate() as $template){
if($template->getName() == $nameToTest){
$hasCustomAttribute=true;
}
}

How to do search filtering through a collection of arrays?

I am going to build advance search function in laravel 5. I queried from 'itemregistrations' table by filtering a few fields such as negeriID, categoryID and operasiID. I need to do array map to calculate age value of each item and put in the array. By getting values using itemregistration table and calculating age runs okay but it problem in searching through the if statement. It cannot searching and retrieve the values through the array in the collection.
$newitem = DB::table('itemregistrations')
->select('itemregistrations.*')
->get();
//added code to get 'age' value:
$newitem->map(function ($detail) {
$detail->age = \Carbon\Carbon::createFromFormat('Y',$detail->lahir_yy)->diffInYears();
return $detail;
});
if ($request->has('negeri_lahir')) {
$newitem->where('NegeriID', '==', $request->negeri_lahir);
}
if ($request->has('kategori')) {
$newitem->where('CategoryID', $request->kategori);
}
if ($request->has('pangkat')) {
$newitem->where('OperasiID', $request->pangkat);
}
dd($newitem->get());
The problem because of the array map added, turning the collection in array values causing this error.
It is producing error:
Type error: Too few arguments to function Illuminate\Support\Collection::get(), 0 passed in C:\xampp\htdocs\
This is the array list in the collection for dd($newitem);
#items: array:1123 [▼
0 => {#709 ▶}
1 => {#680 ▶}
2 => {#681 ▶}
3 => {#712 ▶}
Collection {#671 ▼
#items: array:1123 [▼
0 => {#709 ▼
+"ItemRegistrationID": 1
+"COID": 109064
+"FType": ""
+"STNo": "0"
+"RegistrationDate": "2005-12-01"
and more attributes...
How to enable the searching through the array list?
First of all, you don't need to use select() in query.
Looks like better to make filtering in db query using when().
Try:
$newitem = DB::table('itemregistrations')
->when(request('age'), function($query){
$query->whereRaw('YEAR(curdate()) - lahir_yy >= ?', [request('age')]);
})
->when(request('negeri_lahir'), function($query){
$query->where('NegeriID', request('negeri_lahir'));
})
->when(request('kategori'), function($query){
$query->where('CategoryID', request('kategori'));
})
->when(request('pangkat'), function($query){
$query->where('OperasiID', request('pangkat'));
})
->get();

How to implode an array of arrays in Laravel?

Hi I have the following query:
$inc_quotes = DB::table('inc_quotes')->where('session_id', '=', $session_id)->get();
And it returns an array of arrays I believe like below:
array:36 [▼
0 => {#232 ▼
+"id": "5"
+"session_id": "1ee0556134d377c05673fce16f719b3e1077c797"
+"brand": "Acer"
+"drive": "Full Size Laptop"
+"screen": "Less than 2 Years old"
+"processor": "AMD A6"
+"condition": "No"
+"faults": "Light Damage,Heavy Damage"
+"price": "16.37"
+"name": "Alex"
+"lastname": "C"
+"email": "test#hotmail.com"
+"mobile": "12344567"
+"created_at": "2016-02-20 09:05:51"
+"updated_at": "2016-02-20 09:05:51"
}
1 => {#233 ▶}
2 => {#234 ▶}
Now I would like to extract from each array(row) for example the name and do a for each on the view to show the names for each row.
How can I extract the values?
I tried this
foreach($inc_quotes as $quote){
$quote_name = $quote->name;
}
But only returns the last value.
Any help much appreciated.
$quote_name = [];
foreach($inc_quotes as $key => $quote){
$quote_name[$key] = $quote->name;
}
EDITED
pass this to view like this.
return view('whateverYourView',compact('quote_name'));
and in view you access it with
#foreach($quote_name as $name)
{{ $name }}
#endforeach
Your $quote_name must be an array or an collection to receive all data that is comming from the array that you are iterating.
The $quote_name will be subscribed in every loop, that's why the method it will show only the last result.

Resources