Laravel foreach query builder result - laravel

I try to foreach a result then if name equal to "Apple "then i add a new row to next.
$list= Food::select('id', 'name')->get();
foreach ($list as $l) {
if($l->name == 'Apple'){
//Add 2 more item to next row
}
}
And my result output:
[
{
"id": 1,
"name": "Apple"
},
{
"id": 2,
"name": "Orange"
},
{
"id": 3,
"name": "Blueberry"
},
]
Here the result that i want to, for each to check if name is apple, then i need to add 2 more item manually.
[
{
"id": 1,
"name": "Apple"
},
{
"id": 1.1,
"name": "Apple Pie"
},
{
"id": 1.2,
"name": "Apple Juice"
},
{
"id": 2,
"name": "Orange"
},
{
"id": 3,
"name": "Blueberry"
},
]

For my own part, i use a temp array.
$list= Food::select('id', 'name')->get();
$tempList = array();
foreach ($list as $l) {
$tempList[] = $l;
if($l->name == 'Apple'){
$tempList[] = array('id' => 1.1, 'name' => 'Apple Pie');
}
}
But i think you can use Collection methods like "push"
Collections Push

Related

Laravel createMany error on nested relation

This is in relation to this question. I'm having this error:
TypeError
Illuminate\Database\Grammar::parameterize(): Argument #1 ($values) must be of type array, int given, called in /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php on line 920
While inserting data using createMany. This is the form request data:
{
"name": "My Order",
"orders": [
{
"date": "2022-05-17",
"product_id": [1],
"price": 1
},
{
"start_date": "2022-05-18",
"product_id": [2],
"price": 2
}
]
}
This is the store method:
$order = auth()->user()->orders()->create($request->validated());
$order_subs = $order->subOrders()->createMany($request->orders);
$order_sub_items = $request->only('orders')['orders'];
foreach ($order_subs as $key => $value) {
$value->subOrderProducts()->createMany([$order_sub_items[$key]);
}
However, if the product_id is not an array, it will store properly. Sample form request data:
{
"name": "My Order",
"orders": [
{
"date": "2022-05-17",
"product_id": 1,
"price": 1
},
{
"start_date": "2022-05-18",
"product_id": 2,
"price": 2
}
]
}
How to fix this error?

categories<-subgaterories->plan how to get categories id wise fetch data laravel

**i want **
$PlanDetails= PalnCategory::select('id','title')->with('Categorys'[subplandetails])->get();
my api response
[
{
"id": 1,
"title": "category 1",
"categorys": [
{
"id": 5,
"subcategor_name": "regular"
},
{
"id": 6,
"subcategor_name": "primum"
}
]
},
{
"id": 2,
"title": "category 2",
"categorys": [
{
"id": 7,
"subcategor_name": "cat2 reg"
}
]
}
]
i want to show
[
{
"id":1,
"title":"category 1",
"categorys":[
{
"id":5,
"subcategor_name":"regular",
"plans":[
{
"id":1,
"name":"plan1"
},
{
"id":2,
"name":"plan2"
}
]
},
{
"id":6,
"subcategor_name":"primum",
"plans":[
{
"id":3,
"name":"plan3"
},
{
"id":4,
"name":"plan4"
}
]
}
]
},
{
"id":2,
"title":"category 2",
"categorys":[
{
"id":7,
"subcategor_name":"cat2 reg",
"plans":[
{
"id":3,
"name":"plan3"
},
{
"id":4,
"name":"plan4"
}
]
}
]
}
]
my model
public function Categorys()
{
return $this->belongsToMany(PlanSucategory::class)->select('id','subcategor_name');
}
public function PlanDetails()
{
return $this->belongsToMany(PlanDetail::class);
}
my controller
$PlanDetail= PalnCategory::select('id','title')->with('Categorys','PlanDetails')->get();
return response()->json($PlanDetail);
here subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetails
here subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetailshere subcategories id same anthor to table categories<-subcategories->plandetails but i want to fetch data categories->subcategories->plandetails
I'm not going to modify your query, but instead use a collection, which will transform the data after the get() method.
$PlanDetail = PalnCategory::select('id','title')
->with('Categorys','PlanDetails')
->get()
->groupBy('categorys.0.id')
->values()
->map(function($item){
$sub = collect($item)->map(function($item){
$return = collect($item)->forget(['categorys', 'plan_details'])->all();
$return['plans'] = $item['plan_details'];
return $return;
})->toArray();
$category = $item[0]['categorys'][0];
$category['categorys'] = $sub;
return $category;
});
return response()->json($PlanDetail);
Output :
[
{
"id": 1,
"title": "category 1",
"categorys": [
{
"id": 5,
"subcategor_name": "regular",
"plans": [
{
"id": 6,
"details": "plan1 reg"
}
]
},
{
"id": 6,
"subcategor_name": "primum",
"plans": [
{
"id": 7,
"details": "plan2 reg2"
}
]
}
]
},
{
"id": 2,
"title": "category 2",
"categorys": [
{
"id": 7,
"subcategor_name": "cat2 reg",
"plans": [
{
"id": 8,
"details": "plan1"
}
]
}
]
}
]

Laravel- How to Remove a key from collection?

I have data as below:
[
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
"price": 20
}
]
I want to filter which is is_lottery == false remove the price key from this collection. The output is:
[
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
}
]
You can do this
$json = '[
{
"id": "3",
"title": "Boruto\'s Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "3",
"title": "Misuki\'s Photo",
"is_lottery": 0,
"price": 20
}
]';
$filtered = collect(json_decode($json, true))->map(function ($array) {
if (!$array['is_lottery']) {
unset($array['price']);
}
return $array;
});
For native PHP you can do
$data = json_decode($json, true);
foreach ($data as $index => $array) {
if (!$array['is_lottery']) {
unset($array['price']);
}
$data[$index] = $array;
}
$json = [
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
"price": 20
}
];
$filtered = collect(json_decode($json))->map(function($value, $key) {
if (!$value['is_lottery']) {
Arr::except($value, 'price');
}
return $value;
});
you can declare new variable called $newCollection as final collection. Use foreach() to iterate your collection then delete the is_lottery from collection by using unset() then push it to $newCollection, this is example how you can delete it using foreach:
$newCollection = [];
foreach ($photos as $key => $value) {
if ($value["is_lottery"] == 0) {
unset($value["price"]);
}
array_push($newCollection,$value);
}
or you can try using forget to remove it from collection (not tested) from this ref:
How to unset (remove) a collection element after fetching it?

Laravel - Sort array by string value first and then date

I need help to sort array by couple of logics
[
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
},
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
}
]
what I want to do is to sort the array to status pending show first, and then sort it by the date descending
I already test to using sortByDesc from laravel collection but the array looks like sorted it by just 1 function
$collection = $collection->sortByDesc('date')->sortByDesc(function ($row, $key) {
if($row['status'] == 'pending'){
return 1;
}else{
return 0;
}
});
My expected final result look like this :
[
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
}
]
Few solutions:
Use a custom callback and return an array source
$products->sortBy(function($product) {
return [$product->param1, $product->param2];
});
This will sort a collection by param2 first, and then by param1
Use a custom callback and return a composite property to sort on source
$posts = $posts->sortBy(function($post) {
return sprintf('%-12s%s', $post->column1, $post->column2);
});
Sort your array by column 1, then split it up by column 2 and then merge it again (untested).
$collection->sortByDesc('date');
$collection->groupBy('status');
$collection->keyBy('status');
EDIT: Also I'm not sure if sortByDesc('date') works with date strings.
Your expected result can be achieved like this.
$sorted = $collection
->sortByDesc('date')
->sortBy(function ($item) {
return 'pending' == $item['status'] ? 0 : 1;
})
->values();
To be more precise:
$collection= $collection->sort(
function ($a, $b) {
if(($a->status== $b->status) &&($a->status== 'pending')){
return ($a->date >= $b->date) ? -1 : 1;
}elseif($a->status== 'pending' && ($a->status!= $b->status)){
return 1;
}else{
return ($a->date <= $b->date) ? 1 : -1;
}
}
);
$collection= $collection->sortByDesc('status');

Immutable js updating a Map in a List

Pushing nested data into a Map inside a List
Can anyone tell me:
How do i push a task to either of these users (List items) ideally by specific user id?
Thanks in advance.
My code:
const initialState = Immutable.List([
Immutable.Map({
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
}),
Immutable.Map({
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
})
])
First, the way you're building this structure, the tasks array will not be an immutable instance, I think that is not what you want, you can use Immutable.fromJS to transform all the nested arrays and maps into a Immutable instance.
The way your data is structured you'll have to navigate through the list of users and perform the update when the id matches.
One way of doing that is using map
const initialState = Immutable.fromJS([
{
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
},
{
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
}
]);
let userId = 2;
let newState = initialState.map(user => {
if (user.get('id') !== userId) {
return user;
}
return user.update('tasks', tasks => {
return tasks.push(Immutable.fromJS({
id: 3,
title: "new task",
status: false
}))
});
});
Although this will do what you want,I think you should change your data to a map instead of a list if this kind of operation is something recurrent in your application. This will make things easier and faster.
const initialState = Immutable.fromJS({
"1": {
"id": 1,
"name": "Abe Bell",
"tasks": [
{
"id": 1,
"title": "Get haircut",
"status": false
}
]
},
"2": {
"id": 2,
"name": "Chad Dim",
"tasks": [
{
"id": 2,
"title": "Get real job",
"status": false
}
]
}
});
let userId = "2";
let newState = initialState.updateIn([userId, 'tasks'], tasks => {
return tasks.push(Immutable.fromJS({
id: 3,
title: "new task",
status: false
}));
});

Resources