How to join two tables and get JSON data of all rows - json

I have a 2 tables units table and unit_images table
units
id | unit_types | price
------------------------
1 | Apartment | 100
2 | House | 200
unit_images
id | unit_id | image_name
------------------------
1 | 1 | image1.jpg
2 | 1 | image2.jpg
3 | 2 | image3.jpg
4 | 2 | image4.jpg
How can I achieve this result when I display on the div?
<div>
<p>Apartment</p>
<p>100</p>
<p>image1.jpg</p>
<p>image2.jpg</p>
</div>
<div>
<p>House</p>
<p>200</p>
<p>image3.jpg</p>
<p>image4.jpg</p>
</div>
This is what i've tried
index.blade.php
var apiUrl = 'view';
$.ajax({
type: "GET",
url: apiUrl,
success: function(response) {
let unit_types_result = response.unit_types.map((result) => {
let images_result = response.image.map((result1) => {
return `
<p>${result1.image_name}"</p>`
});
return `
<div>
<p>${result.unit_types}</p>
<p>${result.price}</p>
<p>${images_result}</p>
</div>`
});
unit_types_div.append(unit_types_result);
}
});
ApiController.php
public function view()
{
$unit_types = DB::table('units')
->join('unit_images', 'units.id', '=', 'unit_images.unit_id')
->distinct()
->select('units.unit_types')
->get();
$img = DB::table('units')
->join('unit_images', 'units.id', '=', 'unit_images.unit_id')
->get();
return response()->json([
'status' => true,
'image' => $img,
'unit_types' => $unit_types,
]);
}
On this source code I can display the Apartment and House on separate div but the problem is the 4 images display on each div.

First thing first, you need to create model for each of your table.
And inside each of model class you declare the relationship.
// App\Models\Unit
class Unit extends Model
{
public function images()
{
return $this->hasMany(UnitImage::class);
}
}
// App\Models\UnitImage
class UnitImage extends Model
{
public function unit()
{
return $this->belongsTo(Unit::class);
}
}
And inside your controller now to call the query, use eloquent.
$unit_types = Unit::with('images')->get();
return response()->json([
'status' => true,
'unit_types' => $unit_types,
]);
And this is the result of $unit_types as Json
[
{
"id": 1,
"unit_types": "Apartment",
"price": 100,
"images": [
{
"id": 1,
"unit_id": 1,
"image_name": "image1.jpg"
},
{
"id": 2,
"unit_id": 1,
"image_name": "image2.jpg"
}
]
},
{
"id": 2,
"unit_types": "House",
"price": 200,
"images": [
{
"id": 3,
"unit_id": 2,
"image_name": "image3.jpg"
},
{
"id": 4,
"unit_id": 2,
"image_name": "image4.jpg"
}
]
}
]
And now you can populate your html using js ajax alot easier.
I hope this can help you out.

Related

Can I get Category with id 1 and all Subcategories of that Category in a single query in Sequelize.js?

I have the following database table:
Table: Categories
Columns: id, name, parent_id
and the following records:
1 / Category1 / 0
2 / Category2 / 0
3 / Subcategory1 / 1
4 / Subcategory2 / 1
So I have 2 Categories - Category1 and Category2 and 2 Subcategories of Category1 - Subcategory1 and Subcategory2.
If the parent_id field is 0, that means the record is a Category and if it is not 0 and has the id of another category, then it is a subcategory of that category.
Right now I'm getting all Categories like this:
Category.findAll({
where: {
'parent_id': 0
}
})
.then(result => {
console.log(result)
})
.catch(error => {
console.log(error)
})
but now I also want to somehow include the Subcategories of the Categories as an object property. Right now I'm getting this:
[
{
"id": 1,
"name": "Category1",
"parent_id": 0
}
]
and I want to get something like this:
[
{
"id": 1,
"name": "Category1",
"parent_id": 0,
"subcategories": [
{
"id": 3,
"name": "Subcategory1",
"parent_id": 1,
},
{
"id": 4,
"name": "Subcategory2",
"parent_id": 1,
}
]
}
]
It is similar to eager loading but it is like the model eager loading itself. How can I do this in least queries possible?
You need to use sequelize.define() to create a Model that backs your table, in this case "Category"
// first define your model, you don't have to define the `id` or `parent_id` as they will be created automatically
const Categories = sequelize.define('categories', {
name: {
type: DataTypes.STRING(255),
},
},
{
// use underscores in generated column names
underscored: true,
});
Now create the relationships between parent-<children and child--parent for the Model.
// relate a category to its parent=
Categories.belongsTo(Categories, {
as: 'parent',
foreignKey: 'parent_id',
targetKey: 'id',
});
// relate parent to child categories
Categories.hasMany(Categories, {
as: 'subcategories',
foreignKey: 'parent_id',
});
Now you can use the include option to pass in the Model and specify the as parameter to load the correct relationships. Pass in required: false to use a left join so that results will come back if there are no subcategories.
// ... your code
// now you can include the subcategories and
// pass in the parent_id into the where clause
const category = await Categories.findOne({
include: {
model: Categories,
as: 'subcategories',
required: false,
},
where: {
parent_id: 0,
},
});
// if you know the ID you want is 1...
const category = await Categories.findByPk(1, {
include: {
model: Categories,
as: 'subcategories',
required: false,
},
});
In the reverse direction, from the child to the parent, or in this case both...
// To get a category and its parent and children...
const categoryWithParentAndSubcategories = await Categories.findByPk(123, {
include: [
{
model: Categories,
as: 'parent',
required: false,
},
{
model: Categories,
as: 'subcategories',
required: false,
},
],
});
// you can keep going for multiple levels if you want
// To get a category and its grandparent, parent and children...
const categoryWithParentAndSubcategories = await Categories.findByPk(123, {
include: [
{
model: Categories,
as: 'parent',
required: false,
include: {
model: Categories,
as: 'parent',
required: false,
},
},
{
model: Categories,
as: 'subcategories',
required: false,
},
],
});

filtering by pipe: Template parse Error Angular4

its my first time with "pipe" so I think I missed few things:
I have a JSON file which contain data of products. the products can be sort by "ProductTags" - JSON with the tag they can be filter by. also, I have JSON Which contain details about the filter:
"PriceFilter": [
{
"TagId": 20,
"Type": "Budget",
"Value": 5,
"Values": null,
"DisplayText": "$5",
"Order": null
},
{
"TagId": 21,
"Type": "Budget",
"Value": 10,
"Values": null,
"DisplayText": "$10",
"Order": null
}]
product:
"Products": [
{
"ProductId": 206419,
"ProductTitle": "Mom is Fabulous Fruit Box - Good",
"ProductTags": [ 20, 2, 3, 4 ]
}]
I need to order the products using the tags in this way: price
store. html
<table>
<tr *ngFor="let P of PriceFilter | filter : term | orderBy: 'Price'">
<td>{{PriceFilter.DisplayText}}</td>
</tr>
</table>
store component:
stores=[];
products=[];
PriceFilter = [];
GenderFilter =[];
filtered=[];
constructor(private _storeService:StoreService) { }
ngOnInit() {
this._storeService.getProducts()
.subscribe(data =>{
this.products = data.Stores.Products;
this.stores=data.Stores;
this.PriceFilter = data.PriceFilter;
this.GenderFilter = data.GenderFilter;
console.log(data.PriceFilter)
console.log(data.GenderFilter)
console.log(data.Stores)
});
}
filter pipe:
transform(items: any[], term): any {
console.log('term', term);
return term
? items.filter(item => item.ProductTags.indexOf(term) !== -1)
: items;
}
orderBy pipe:
export class OrderbyPipe implements PipeTransform {
transform(items: any[], orderBy: string): any {
console.log('orderdBy', orderBy);
return items.sort((a, b) => {return b[orderBy] - a[orderBy]});
}

Can't get certain data from JSON, returns undefined Angular 6

I'm trying to extract "data" from this JSON but it keeps throwing undefined as result.
Extract of code where I'm getting this error:
ngOnInit(): void {
this.testService.getTestWithObservable().subscribe(
res => {
let user = res["users"];
let user_data = user["data"];
this.user_data = user_data;
console.log(user_data);
console.log(res);
}
);
}
res outputs the whole JSON but user_data throws:
ERROR TypeError: Cannot read property 'data' of undefined
at SafeSubscriber._next
JSON
[{
"id": 1,
"users": {
"user_id": 14,
"data": [{
"name": "James",
"age": 20
},
{
"name": "Damien",
"age": 25
}]
}
}
{
"id": 2,
"users": {
"user_id": 11,
"data": [{
"name": "James",
"age": 20
},
{
"name": "Damien",
"age": 25
}]
}
}]
Your JSON is an array so you need to use an index or a loop to access one of your item like this:
ngOnInit(): void {
this.testService.getTestWithObservable()
.subscribe(
res => res.forEach(user => this.user_data = [...(this.user_data || []), user['users']['data']]);
);
}
Or:
ngOnInit(): void {
this.testService.getTestWithObservable()
.subscribe(
res => this.user_data = res[0]['users']['data']);
);
}
The first code will store in the user_data array all the data prop of each users
The result is array so you have to use index to access to the array data ,
this.testService.getTestWithObservable()
.map( result => result.map( i => i.users.data) ) // array of data array
.subscribe(
res => {
this.user_data = [];
res.forEach(i => this.user_data(...i));
console.log(this.user_data); // all users data as array
}
);
}
loop throw the data by ngFor
<div *ngFor="let user of user_data">
{{user.name}} , age : {{user.age}}
</div>

Try to get key values recursively from JSON in Angular 5

I want to retrieve all the key values from a JSON file. For example in :
{
"total_count": 6,
"incomplete_results": false,
"items": [
{
"url": "https://api.github.com/repos/Samhot/GenIHM/issues/6",
"id": 293237635,
"number": 6,
"title": "Rechercher des documents",
"user": {
"login": "Samhot",
"id": 7148311
]
}
I would like to get :
["total_count", "incomplete_results", "items", "url", "url", "number", "title", "user", "login", "id"]
I have a function which return the content of my JSON in an observable :
getConfig(): Observable<any> {
return this.http.get<any>(this.myURL);
}
After that the data are reformated with .map to get only the keys with the Object.keys() function :
merge()
.pipe(
startWith({}),
switchMap(() => {
return this.getConfig();
}),
map(data => {
return Object.keys(data.items[0]);
}
)
)
.subscribe(data => {
this.dispo = data;
});
My problem is that i get only the keys that are in the level of the JSON I told
(data.items[0]) and not the ascendants or the descendants.
Of course I can create multiple requests but it asks to know in advance the structure of the JSON, what I want is to make it generic ...
How can I do to have an array with with all of my keys regardless of the structure of the JSON ?
Thanks in advance !
You would need to do a recursive function like:
function getDeepKeys(obj) {
const keys = Object.keys(obj);
const childKeys = keys
.map(key => obj[key])
.map(
value =>
Array.isArray(value)
? getDeepKeys(value[0])
: typeof value === "object"
? getDeepKeys(value)
: []
)
.reduce((acc, keys) => [...acc, ...keys], []);
return [...keys, ...childKeys];
}
const obj = {
total_count: 6,
incomplete_results: false,
items: [
{
url: "https://api.github.com/repos/Samhot/GenIHM/issues/6",
id: 293237635,
number: 6,
title: "Rechercher des documents",
user: {
login: "Samhot",
id: 7148311
}
},
{
url: "https://api.github.com/repos/Samhot/GenIHM/issues/6",
id: 293237635,
number: 6,
title: "Rechercher des documents",
user: {
login: "Samhot",
id: 7148311
}
}
]
};
console.log(getDeepKeys(obj));
Which then you would use like map(getDeepKeys). Note that this function assumes all the items in your array have the same schema.

Bookshelf.js get pivot table attributes

I am trying to get attributes from my m-n relational mySql table using Bookshelf.js.
I have a table users: id, name
and tournaments: id, place
and a pivot table: user_id, tournament_id, teamname
Those are my models:
var User = Bookshelf.Model.extend({
tableName: 'users',
tournaments: function () {
return this.belongsToMany(Tournament);
}
});
var Users = Bookshelf.Collection.extend({
model: User
});
var Tournament = Bookshelf.Model.extend({
tableName: 'tournaments',
users: function () {
return this.belongsToMany(User);
}
});
var Tournaments = Bookshelf.Collection.extend({
model: Tournament
});
var Tournaments_Users = Bookshelf.Model.extend({
tableName: 'tournaments_users'
});
Now when I do
Tournaments.forge().fetch({withRelated: ['users']})
.then(function (collection) {
res.send(collection.toJSON());
})
I get
{
"id": 1,
"place": "Berlin",
"users": [
{
"id": 1,
"name": "Jim",
},
{
"id": 2,
"name": "Tom",
}, ...
}
What I want:
{
"id": 1,
"place": "Berlin",
"users": [
{
"id": 1,
"name": "Jim",
"teamname" : "Team A"
},
{
"id": 2,
"name": "Tom",
"teamname" : "Team B"
}, ...
}
Anyone knows how to do this using Bookshelf?
You may use .withPivot() method.
Use it like this :
users: function () {
return this.belongsToMany(User).withPivot(['teamname']);
}
In your return, you will get a field named _pivot_teamname. Just rename them to get it good.
Documentation : http://bookshelfjs.org/#Collection-instance-withPivot
As long as I know, there is no way to fetch the pivot fields with a custom name.