Resultset mapper or formatter in Cakephp 3 - cakephp

I have 2 Collections/ Result sets the first one is products and second one is sizes
"products": [
{
"category_id": 5,
"id": 5,
"code": "A",
"name": "Pizzabrot",
"description": "",
"product_prices": [
{
"product_id": 5,
"price": 2.5,
"size_id": 15
},
{
"product_id": 5,
"price": 3.5,
"size_id": 16
}
]
},
{
"category_id": 5,
"id": 6,
"code": "B",
"name": "Pizzabrot mit Knoblauch",
"description": "",
"product_prices": [
{
"product_id": 6,
"price": 3,
"size_id": 15
},
{
"product_id": 6,
"price": 4,
"size_id": 16
}
]
}]
AND
"sizes": [
{
"id": 15,
"name": "Klein",
"category_id": 5
},
{
"id": 16,
"name": "Gro\u00df",
"category_id": 5
}
]
I want to replace every product_prices.size_id with it's name from sizes Collection

From what I can see it would probably be better to associate ProductPrices and Sizes and fetch them with your Products.
If this does not fit your needs for some reason, you could find the sizes by using a find('list') (see Docs) like this:
$query = $this->Sizes->find('list', [
'keyField' => 'id',
'valueField' => 'name'
]);
$sizes = $query->toArray();
Then loop through the products and its product_prices and do something like.
$product_price->size_id = $sizes[$product_price->size_id];
Please prefer the first solution. ;-)

Related

Avoid using arrays (and [0]) in multidimensional JSON object

I'm storing data in a JSON file and need different objects/arrays. So far I am using the following structure:
data= [
{
"savedRuns": [
{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
]
},
{
"groups": [
{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
]
},
{
"locations": [
{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}
]
I would like to access the data in the file in an easy way, for instance:
console.log(data.savedRuns)
console.log(data.locations)
Unfortunately this returns undefined and the only way to access the data is:
console.log(data[0].savedRuns);
console.log(data[2].locations);
Since I don't necessarily know the position of the object, I would like to avoid that. If there a way around this, or a different structure to adopt for my file?
Link to JSFiddle
You have each attribute in a separate object, stored in an array. Get rid of the outer array and store the attributes in one object, then use data.savedRuns.
Thanks to Marks answer I could get the right syntax. Posting below in case of interest to others.
data = {
"savedRuns": [{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
],
"groups": [{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
],
"locations": [{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}

How to filter elements of an array based on a property inside double nested array

Well, i have a complicated issue. at least it is complicated for myself.
So i have an Array which has an Array that has an Array in it.
and i want to filter The very top array based on properties inside the deepest array.
Lets say i have this Array of objects
var garages = [{
"GarageId": 1,
"GarageName": "Garage_001",
"Sections": [{
"SectionId": 1,
"Name": "Section_002",
"Cars": [{
"Id": 5,
"Model": "Bmw"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}, {
"SectionId": 2,
"Name": "Section_003",
"Cars": [{
"Id": 8,
"Model": "Toyota"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}]
},
{
"GarageId": 6,
"GarageName": "Garage_006",
"Sections": [{
"Id": 1,
"Name": "Section_007",
"Cars": [{
"Id": 5,
"Model": "Bmw"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}, {
"Id": 2,
"Name": "Section_003",
"Cars": [{
"Id": 8,
"Model": "Toyota"
}, {
"Id": 6,
"Model": "Mercedes"
}]
}]
}
]
And i want to retrieve a list of garages that contain a Hyundai for example. how can i do it?
i have been trying for hours and this is what i came up with. it may be a stupid piece of code but i just got confused dealing with this much nested Arrays!
So my code is this:
garages: any[] = [];
selectedCarModel: number: 8;
filterOnCarModel(carId) {
this.garages = getGaragesFromServed();
this.selectedCarModel = this.CarModels.find(c => c.Id == id);
let filteredArray = this.garages
.filter((garage) =>
garage.Sections).
filter((section) =>
study.Cars.find((car) => car.Id == carId));
this.garages = filteredArray;
}
Thank you for understanding
var filteredGarages = garages.filter(garage =>
garage.Sections.filter(section =>
section.Cars.filter(car => car.Model.indexOf("Bmw")>=0)
.length > 0)
.length > 0)

Typescript : Find common objects from two array using Lambda function

I am using Typescript for below problem. I want to search object not simple alphabetic or number in the list.
Below are the two arrays.
I want to get common objects in separate list without using any third party library.
firstArray = [
{
"id": 4,
"name": "Tata"
},
{
"id": 11,
"name": "Maruti"
},
{
"id": 14,
"name": "Mahindra"
}
]
secondArray = [
{
"id": 4,
"name": "Tata"
},
{
"id": 11,
"name": "Maruti"
},
{
"id": 15,
"name": "Hyundai"
},
{
"id": 21,
"name": "Honda"
}
]
// Get Common Elements
// I am getting blank array as output
console.log(firstArray.filter(( make ) => secondArray.includes( make)));
Is there good function or way to find out commons element?
You can use array#filter with array#some. For each object in the first array, check if id and name exist in the other array.
const firstArray = [{ "id": 4, "name": "Tata" }, { "id": 11, "name": "Maruti" }, { "id": 14, "name": "Mahindra" } ],
secondArray = [{ "id": 4, "name": "Tata" }, { "id": 11, "name": "Maruti" }, { "id": 15, "name": "Hyundai" }, { "id": 21, "name": "Honda" } ],
result = firstArray.filter(o => secondArray.some(({id,name}) => o.id === id && o.name === name));
console.log(result);
For ES6, you can also try sets,
For demonstration,
const thirdArray = [...new Set([...firstArray ,...secondArray])];

CakePHP controller method to fetch data from multiple related tables

Currently i am working with CakePHP 3.x and have a following use case.
Department (id, name, description)
Designations (id, name, description)
Users (id, name, description)
DepartmentDesignations (id, departments_id, designations_id)
DepartmentDesignationUsers (id, department_designations_id, users_id)
Above mentioned are 5 different tables and their columns are listed in brackets. Following is the relationship between these.
Department has many designations. So in order to handle this i have created another DepartmentDesignations.
DepartmentDesignations has many users. So in order to handle this i have created DepartmentDesignationUsers.
I have defined following function in DepartmentsController and my expectation is that i need to get all the following information in single call.
- all the departments
- all the designations in each department (if any)
- all the users for each department designation (if any)
public function index()
{
$departments = $this->Departments->find('all')
->contain('DepartmentDesignations.Designations')
->contain('Users');
$this->set(compact('departments'));
$this->set('_serialize', ['departments']);
}
I have also defined the following in DepartmentsTable.php
$this->belongsToMany('Designations', [
'joinTable' => 'department_designations',
'foreignKey' => 'departments_id',
'targetForeignKey' => 'designations_id'
]);
$this->hasMany('DepartmentDesignations', [
'className' => 'OrganizationManagement.DepartmentDesignations',
'foreignKey' => 'departments_id'
]);
$this->hasMany('DepartmentDesignationUsers',[
'className' => 'OrganizationManagement.DepartmentDesignationUsers',
'foreignKey' => 'department_designations_id'
]);
$this->belongsToMany('Users',[
'joinTable' => 'department_designation_users',
'foreignKey' => 'department_designations_id',
'targetForeignKey' => 'users_id'
]);
I get the following response.
{
"departments": [
{
"id": 1,
"name": "Organization",
"description": "",
"parent_id": 0,
"users": [],
"department_designations": [
{
"id": 1,
"departments_id": 1,
"designations_id": 1,
"designation": {
"id": 1,
"name": "Brand head",
"description": "",
"level": 1
}
},
{
"id": 6,
"departments_id": 1,
"designations_id": 6,
"designation": {
"id": 6,
"name": "CEO",
"description": "",
"level": 1
}
}
]
},
{
"id": 2,
"name": "Production",
"description": "",
"parent_id": 1,
"users": [],
"department_designations": [
{
"id": 3,
"departments_id": 2,
"designations_id": 5,
"designation": {
"id": 5,
"name": "Production assistant manager",
"description": "",
"level": 3
}
},
{
"id": 5,
"departments_id": 2,
"designations_id": 4,
"designation": {
"id": 4,
"name": "Production head",
"description": "",
"level": 2
}
}
]
},
{
"id": 3,
"name": "R&D",
"description": "",
"parent_id": 1,
"users": [],
"department_designations": [
{
"id": 2,
"departments_id": 3,
"designations_id": 2,
"designation": {
"id": 2,
"name": "R&D Manager",
"description": "",
"level": 2
}
}
]
},
{
"id": 4,
"name": "Development",
"description": "",
"parent_id": 3,
"users": [],
"department_designations": [
{
"id": 4,
"departments_id": 4,
"designations_id": 2,
"designation": {
"id": 2,
"name": "R&D Manager",
"description": "",
"level": 2
}
}
]
},
{
"id": 5,
"name": "Purchase",
"description": "",
"parent_id": 1,
"users": [],
"department_designations": []
}
]
}
I need the user information within department_designations array. So in this case what changes i need to do.
On the basis of your information there is no direct relation between
Departments and Users table, So you can not use contain that way for users.
Make it something like this:
public function index()
{
$departments = $this->Departments->find('all')
->contain('DepartmentDesignations.Designations','DepartmentDesignations.DepartmentDesignationUsers.Users');
$this->set(compact('departments'));
$this->set('_serialize', ['departments']);
}
See here: Retrieving Associated Data in CakePHP3.

Lodash for reagrup complex Array[object]

I'm a newbie but i thing this is for Senior Lodash Programmer
I'm new to Lodash and trying to solve this problem but could find a good way to do it.
I have an array of orders and an array of lines with one ticket into each order.
The data is structured as below:
[{
"id": 201,
"order": "Buyer 1",
"lines": ▿[
▿{
"id": 1,
"ticket": ▿{
"id": 151,
"event": ▿{
"id": 31,
"name": "Event 1"
},
"name": "Event 1 Ticket 1",
"price": 39,
"minimum": 1,
"maximum": 5
},
"quantity": 1
},
▿{
"id": 2,
"ticket": {
"id": 152,
"event": {
"id": 31,
"name": "Event 1"
},
"name": "Event 1 Ticket 2",
"price": 60,
"minimum": 2,
"maximum": 4
},
"quantity": 5
},
▿{
"id": 3,
"ticket": {
"id": 153,
"event": {
"id": 33,
"name": "Event 1"
},
"name": "Event 3 Ticket 2",
"price": 60,
"minimum": 2,
"maximum": 4
},
"quantity": 5
}
],
"created_at": "2016-12-22T17:58:27+0000"
},
...]
I need to group all orders by event name and need the next structure:
[{
"event_id": 31,
"event_name":"Event 1",
"total_tickets": 6,
"total_sold": 339
"orders": [
{
"id": 201,
"order": "Buyer 1"
},
....
]},
{
"event_id": 33,
"event_name":"Event 3",
"total_tickets": 5,
"total_sold": 300
"orders":[
{
"id": 201,
"order": "Buyer 1"
}
]},
....
]
"total_tickets" -> sum of order' tickets (quantity) of event
"total_sold" -> sum of order' (price* quantity) of event
Any help will by very usefull
Take a look at _.reduce (or even vainilla JS Array.reduce)
As a friendly advice, try to imagine and sketch - in your mind, or a paper - what exactly needs be done with that data and then start looking for the tools to do it, not the other way around.

Resources