Merge results of query - laravel

I have a query that outputs its values as json in the following format:
[
{
"name":"Bob",
"date":"2016-02-05 00:00:00",
"value":34
},
{
"name":"John",
"date":"2016-02-05 00:00:00",
"value":5
},
{
"name":"Bob",
"date":"2016-02-05 00:00:00",
"value":3
},
{
"name":"Sarah",
"date":"2016-02-05 00:00:00",
"value":56
}
...
]
I need to put this data into the form:
[
{
"name":"Bob",
"data": [
[2016-02-05 00:00:00, 34],
[2016-02-05 00:00:00, 3]
]
},
{
"name":"John",
"data": [
[2016-02-05 00:00:00, 5]
]
},
{
"name":"Sarah",
"data": [
[2016-02-05 00:00:00, 56]
]
}
...
]
Or in other words, I need to combine the results that share a name and put the data into an array data, where each array holds the date and value.
The original json data is held in a variable $results:
foreach ($results as $result)
{
//
}
How do I achieve this?

Something like
function process_results($results) {
$out = [];
foreach ($results as $result) {
$name = $result['name'];
if ( ! $out[$name]) {
$out[$result['name']] = array( 'name' => $name, 'data' => array());
}
array_push($out[$name]['data'], array($result['date'], $result['value']));
}
return array_values($out);
}
This also seems to work
function process_results($results) {
return array_values(array_reduce($results, function($acc, $result) {
$name = $result['name'];
if ( ! $acc[$name]) {
$acc[$result['name']] = array( 'name' => $name, 'data' => array());
}
$acc[$name]['data'][] = array($result['date'], $result['value']);
return $acc;
}, []));
}

Related

How can I add pagination in Lumen 8 collection?

I am using Lumen to create api where I integrate collection. All code details are given below. I want to add pagination according to my code. How I add paginator in my code?
In Controller:
//To get all Employee Type
public function getAllEmployeeTypes(){
$employeeType = OsEmployeeType::where('status',1)->orderBy('priority', 'DESC')->get();
return new OsEmployeeTypeCollection($employeeType);
}
In Collection it looks like
public function toArray($request)
{
return [
'data' => $this->collection->map(function($data) {
return [
'id' => $data->id,
'name' => $data->name,
'priority' => $data->priority,
'status' => $data->status,
];
})
];
}
public function with($request)
{
return [
'success' => true,
'status' => 200
];
}
and the response that I got
{
"data": [
{
"id": 3,
"name": "Type 3",
"priority": 3,
"status": 1
},
{
"id": 2,
"name": "Type 2",
"priority": 2,
"status": 1
},
{
"id": 1,
"name": "Type 1",
"priority": 1,
"status": 1
}
],
"success": true,
"status": 200
}
How can I paginate my API response?
Paginate is the same as Laravel in Lumen. You will do just the same as in Laravel.
$employeeType = OsEmployeeType::where('status',1)->orderBy('priority', 'DESC')->skip(10)->take(5)->get();

store my fetched data to my array const = players

newbie here. My target is to store my fetched data in my array. T
This is my script. This script function is to join 2 data in 1 if they have the same level. For example player 1 has level 1, player 6 has level 1 also, which means that Player 1 and player 6 will be joined in 1 array. This current script is static, it is not dynamic yet. My target is to store my fetched data here rather than the static ones. Thank you in advance, any help will be appreciated.
const players = [
{
id: 1,
name: 'player1',
level: '1',
},
{
id: 2,
name: 'player2',
level: '2',
},
{
id: 3,
name: 'player3',
level: '3',
},
{
id: 4,
name: 'player4',
level: '3',
},
{
id: 5,
name: 'player5',
level: '2',
},
{
id: 6,
name: 'player6',
level: '1',
}
];
const matching = (list, keyGetter) => {
let mapping = {};
const map = new Map();
list.forEach((item) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
Array.from(map).map(([key, value]) => Object.assign(mapping, { [key]: value }));
return mapping
}
const result = matching(players, ({ level}) => { return level});
console.log("RESULT", result);
this is the result of the above script
In this function, this is how i fetch my data. My target is to store my fetched data to the array i made above const = players
views:
<table id="table_player" class="table table-bordered table-hover" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>Player</th>
<th>Level</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
ajax:
$(document).ready(function() {
//datatables
table = $('#table_player').DataTable({
dom: 'lBfrtip',
buttons: [
'print', 'csv', 'copy', 'excel', 'pdfHtml5'
],
"processing": false, //Feature control the processing indicator.
"serverSide": true, //Feature control DataTables' server-side processing mode.
"order": [], //Initial no order.
// Load data for the table's content from an Ajax source
"ajax": {
"url": "<?php echo site_url('controller/ajax_list')?>",
"type": "POST",
"data": function (dateParams) {
return $.extend( { "start": dateParams.start,
"end": dateParams.end,}, dateParams, {
});
},
},
//Set column definition initialization properties.
"columnDefs": [
{
"targets": [ 0 ], //first column
"orderable": false, //set not orderable
},
{
"targets": [ -1 ], //last column
"orderable": false, //set not orderable
},
],
});
});
Controller:
public function ajax_list()
{
$list = $this->model->get_datatables();
$data = array();
$no = $_POST['start'];
foreach ($list as $person) {
$no++;
$row = array();
$row[] = $person->id;
$row[] = $person->player;
$row[] = $person->level;
$data[] = $row;
}
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->model->count_all(),
"recordsFiltered" => $this->model->count_filtered(),
"data" => $data,
);
//output to json format
echo json_encode($output);
}
Model:
var $table = 'tbl_player';
var $column_order = array(null,'id','player','level');
var $order = array('id' => 'desc');
var $column_search = array('id','player','level');
//set column field database for datatable orderable //set column field database for datatable searchable just firstname , lastname , address are searchable var $order = array('id' => 'desc'); // default order
private function _get_datatables_query()
{
$this->db->from($this->table);
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['search']['value']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item, $_POST['search']['value']);
}
else
{
$this->db->or_like($item, $_POST['search']['value']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['order'])) // here order processing
{
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
function get_datatables()
{
$this->_get_datatables_query();
if($_POST['length'] != -1)
$this->db->limit($_POST['length'], $_POST['start']);
$query = $this->db->get();
return $query->result();
}
function count_filtered()
{
$this->_get_datatables_query();
$query = $this->db->get();
return $query->num_rows();
}
public function count_all()
{
$this->db->from($this->table);
return $this->db->count_all_results();
}

return user model with eager loading laravel

return $data =InteractiveSession::with('messages.user')->where('exercise_id',$exercise->id)->first();
This code will return data like below
{
"id": 1,
"exercise_id": 48,
"messages": [
{
"id": 1,
"from_user": 69,
"message": "Hi",
"interactive_session_id": 1,
"user": {
"id": 69,
"first_name": "Jobin"
}
}
]}
how can i return data like below??
{
"id": 1,
"exercise_id": 48,
"messages": [
{
"id": 1,
"from_user":{
"id": 69,
"first_name": "Jobin"
},
"message": "Hi",
"interactive_session_id": 1,
}
]}
i have tables interactivesession,message,users, using hasmany relation
You can create a relation for from_user to the user model, and then do return $data = InteractiveSession::with(['messages.user', 'fromUser'])->where('exercise_id',$exercise->id)->first(); (remember fromUser should be your relation name)
Try this:
$data = InteractiveSession::with('messages.user')->where('exercise_id',$exercise->id)->first();
$data->transform(function($record) {
$messages = $record->messages->transform(function($message) {
'id' => $message->id,
'from_user' => [
'id' => $message->user->id,
'first_name' => $message->user->first_name
],
'message' => $message->message,
'interactive_session_id' => $message->interactive_session_id
});
return [
'id' => $record->id,
'exercise_id' => $record->exercise_id,
'messages' => $messages
];
});

Laravel: How to access Object inside an array

I trying to return access the attributes inside a array of object and it is giving this error Exception: Property [id] does not exist on this collection instance.
Here is what I have tried:
protected function formatted($classroom)
{
return [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => [
'id' => '$classroom->courses->coursteachers->id',
'email' => '$classroom->courses->coursteachers->email',
'uid' => '$classroom->courses->coursteachers->uid',
]
],
];
}
And here is the actual data:
"courses": [
{
"id": 1,
"name": "Analytics",
"slug": "analytics",
"status_id": 1,
"deleted_at": null,
"pivot": {
"classroom_id": 2,
"courses_id": 1
},
"coursteachers": [
{
"id": 3,
"uid": "S0120-46890",
"email": "teacher#vschool.com",
"user_type": "Teacher",
}]
}]
You need to iterate through courses and also courseteachers since they both represent an array but rather an object
protected function formatted($classroom)
{
$result = [];
foreach($classroom->courses as $course) {
$result[] = [
'courses' => [
'id' => $classroom->courses->id,
'name' => $classroom->courses->name,
'slug' => $classroom->courses->slug,
'coursteachers' => $this->getCourseTeachers($cours)
],
];
}
return $result;
}
private function getClassroomTeachers($classroom) {
$result = [];
foreach($classroom->courses as $cours)
{
foreach ($cours->coursteachers as $key => $teacher) {
$result[] = [
// 'coursteachers'=> [
'id' => $teacher->id,
'email' => $teacher->email,
'uid' => $teacher->uid,
'last_name' => $teacher->profile->last_name,
'first_name' => $teacher->profile->first_name,
'middle_name' => $teacher->profile->middle_name,
// ],
];
}
}
return $result;
}
Since courses is an array, you should pick an object using the proper index.
Foe example: try $classroom->courses[0]->id instead of $classroom->courses->id. Here, '0' is the index.
Also it is better if you check if the index exists before you do it. For an example.
'id' : isset($classroom->courses[$index]) ? $classroom->courses[$index]->id : ''
Edit:
In case of a Eloquent collection you should use $classroom->courses->get($index)->id instead of array like retrieval.

How to get the size of an array in document using MongoDB Laravel Query

i have the data
{
"_id": {
"$oid": "5e8e1be5a78b4479443eae43"
},
"vehicle_component_id": 3,
"damages_types": [
1,
7
],
"mileages": [
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0"
],
"damages": {
"1": {
"upper_bound": [
null
],
"damages": [
"0"
],
"lower_bound": [
null
]
},
"7": {
"upper_bound": [
null
],
"damages": [
"0"
],
"lower_bound": [
null
]
}
},
"created_at": "2020-04-08 20:45:57",
"updated_at": "2020-04-08 20:45:57"
}
and trying to get the size or length of the mileages array the mongo query is
db.vehicle_component_damages_values.aggregate(
{ $match: { vehicle_component_id: 3} },
{$project: { count: { $size:"$mileages" }}}
)
and it's returning 10 as expected but when trying with jenssegers/laravel-mongodb like
$query = DB::connection($this->mongoCon)->collection($this->table)->raw(function($collection) use ($vehicleComponentId) {
return $collection->aggregate([
['$match' => ['vehicle_component_id' => $vehicleComponentId]],
[
'$project' => [
'count' => [
'$size' => '$mileages'
]
]
],
]);
});
it's returning
MongoDB\Driver\Cursor {#550}
so my final code for this is
public function findMileagesSizeByVehicleComponentId($vehicleComponentId)
{
try {
$cursor = DB::connection($this->mongoCon)->collection($this->table)->raw(function ($collection) use (
$vehicleComponentId
) {
return $collection->aggregate([
['$match' => ['vehicle_component_id' => $vehicleComponentId]],
[
'$project' => [
'count' => [
'$size' => '$mileages',
],
],
],
]);
});
$result = $cursor->toArray();
if (!empty($result)) {
if (sizeof($result) == 1) {
return iterator_to_array($result[0])['count'];
} else {
throw new ValidationError("Result has multiple counts please check your query.");
}
} else {
return 0;
}
} catch (\Throwable $e) {
return Error::handel($e);
} catch (\Exception $e) {
return Error::handel($e);
}
}

Resources