TypeORM find method returns non-sense data - sql

So I'm trying to make a simple GET route to get some orders from my DB.
My Order entity looks like that :
#Entity('orders')
export class Order extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#CreateDateColumn()
createdAt: string;
#Column()
price: number;
#ManyToOne(() => Status, (status) => status.order)
status: Status;
#OneToMany(
() => OrderHaveProducts,
(OrderHaveProducts) => OrderHaveProducts.product
)
products: OrderHaveProducts[];
}
And I'm trying to get with each order, the products ordered, that are stored in another table and I'm using the entity called OrderHaveProducts that looks like that:
#Entity('orders_have_products')
export class OrderHaveProducts extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#ManyToOne(() => Order, (order) => order.products)
#JoinColumn({ name: 'order_id' })
order: Order;
#ManyToOne(() => Product, (product) => product.orders)
#JoinColumn({ name: 'product_id' })
product: Product;
#ManyToMany(() => Ingredient)
#JoinTable({
name: 'ordered_products_have_removed_ingredients',
joinColumn: {
name: 'ordered_product_id',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'ingredient_id',
referencedColumnName: 'id',
},
})
removed_ingredients: Ingredient[];
#ManyToMany(() => Ingredient)
#JoinTable({
name: 'custom_products_have_ingredients',
joinColumn: {
name: 'ordered_product_id',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'ingredient_id',
referencedColumnName: 'id',
},
})
added_ingredients: Ingredient[];
}
In my DB, in my OrderHaveProducts table I have this data:
OrderHaveProducts table in PHPMyAdmin
Where product_id 4 is a pizza called "BBQ" and product_id 2 is a pizza called "Margarita".
The issue I have is that when I execute this code:
const orders: Order[] = await Order.find({
relations: {
status: true,
products: {
product: true,
removed_ingredients: true,
added_ingredients: true,
},
},
});
The JSON returned is this:
{
"status": 200,
"data": {
"orders": [
{
"id": 1,
"createdAt": "2023-02-11T22:50:18.721Z",
"price": 27,
"status": {
"id": 4,
"name": "finished"
},
"products": []
},
{
"id": 2,
"createdAt": "2023-02-11T22:50:18.735Z",
"price": 15,
"status": {
"id": 4,
"name": "finished"
},
"products": [
{
"id": 1,
"product": {
"id": 2,
"name": "Margarita",
"price": 12,
"picture: "https://medias.delarte.fr/media/sys_master/images/hdb/h49/8875895488542.png"
},
"removed_ingredients": [
{
"id": 5,
"name": "mozzarella",
"stock": 50
}
],
"added_ingredients": []
}
]
}
]
}
}
Where we can clearly see that my first order doesn't have any product (when in DB we see that it has 2) and the second order has 1 product (as expected) but it's not the good product.
I tried to only get the data from the OrderHaveProducts table and I successfuly get the data I see in my DB:
{
"status": 200,
"data": {
"orders": [
{
"id": 1,
"order": {
"id": 1,
"createdAt": "2023-02-11T22:50:18.721Z",
"price": 27
},
"product": {
"id": 2,
"name": "Margarita",
"price": 12,
"picture": "https://medias.delarte.fr/media/sys_master/images/hdb/h49/8875895488542.png"
}
},
{
"id": 2,
"order": {
"id": 1,
"createdAt": "2023-02-11T22:50:18.721Z",
"price": 27
},
"product": {
"id": 4,
"name": "BBQ",
"price": 15,
"picture": "https://cdn.shopify.com/s/files/1/0508/2179/1903/articles/25-Comment_cuire_pizza_barbecue_1500x.jpg?v=1619600472"
}
},
{
"id": 3,
"order": {
"id": 2,
"createdAt": "2023-02-11T22:50:18.735Z",
"price": 15
},
"product": {
"id": 4,
"name": "BBQ",
"price": 15,
"picture": "https://cdn.shopify.com/s/files/1/0508/2179/1903/articles/25-Comment_cuire_pizza_barbecue_1500x.jpg?v=1619600472"
}
}
]
}
}
If anyone can tell me what is going on with all of this it would be incredible, thanks !

I finally found the issue (issues ?). I actually had wrongly set up my relations between my Order entity and OrderHasProducts.
So in my Order entity my relation was like that:
#OneToMany(
() => OrderHaveProducts,
(OrderHaveProducts) => OrderHaveProducts.product // <-- Here I linked the entity to the product, when I should have linked it to order
)
products: OrderHaveProducts[];
So the good relation should have been this:
#OneToMany(
() => OrderHaveProducts,
(OrderHaveProducts) => OrderHaveProducts.order
)
products: OrderHaveProducts[];
And the second issue was coming from the OrderHaveProducts entity where I, another time, miss linked the entities, so I had this :
#ManyToOne(() => Order, (order) => order.products)
#JoinColumn({ name: 'order_id' })
order: Order;
#ManyToOne(() => Product, (product) => product.orders)
#JoinColumn({ name: 'product_id' })
product: Product;
When the good relation should have been this:
#Column()
order_id: number;
#Column()
product_id: number;
#ManyToOne(() => Order, (order) => order.id)
#JoinColumn({ name: 'order_id' })
order: Order;
#ManyToOne(() => Product, (product) => product.id)
#JoinColumn({ name: 'product_id' })
product: Product;
So now I successfuly get the good data.
Hope it can help anyone in the future ;)

Related

Find documents by autopopulated fields Mongodb

here is my Schema.
const PromocodeSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User', autopopulate: true },
promocode_name: { type: String },
promocode: { type: String },
)}
How can I find this document by first_name of user_id which is a auto populated field
"_id": "60531cd4a0db4a3f09c2dcb8",
"user_id": {
"first_name": "ART",
"last_name": "INMOVE",
"domain": "test2.com",
},
"promocode_name": "Art10",
"promocode": "ART10",
"discount_percentage": 10,

Ramda - how to merge 2 or more arrays of objects

I am trying to merge arrays of objects into one clean array using Ramda but I need some help. I have sample JSON which is below. In this example, I have 2 groups but the number of groups can be 3, 4, 10. I am interested in tableItems array from each group.
const groups = [
{
id: '',
name: '',
tableItems: [
{
id: 1,
name: 'John'
},
{
id: 2,
name: 'Paul'
},
{
id: 3,
name: 'Mary'
}
]
},
{
id: '',
name: '',
tableItems: [
{
id: 10,
name: 'Brian'
},
{
id: 20,
name: 'Joseph'
},
{
id: 30,
name: 'Luke'
}
]
}
];
I tried something like this:
let mapValues = x => x.tableItems;
const testItems = R.pipe(
R.map(mapValues)
)
And then I got arrays of my tableItems and now I would like to merge them into one array.
[
[
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Paul"
},
{
"id": 3,
"name": "Mary"
}
],
[
{
"id": 10,
"name": "Brian"
},
{
"id": 20,
"name": "Joseph"
},
{
"id": 30,
"name": "Luke"
}
]
]
Any help would be appreciated.
Use R.chain to map and flatten, and get the tableItems using R.prop:
const fn = R.chain(R.prop('tableItems'));
const groups = [{"id":"","name":"","tableItems":[{"id":1,"name":"John"},{"id":2,"name":"Paul"},{"id":3,"name":"Mary"}]},{"id":"","name":"","tableItems":[{"id":10,"name":"Brian"},{"id":20,"name":"Joseph"},{"id":30,"name":"Luke"}]}];
const result = fn(groups);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

Mongoose Schema - How to add an order attribute for sorting

I am currently building a web application where you can create setlists (arrays) with an array of lyric objectId's inside, that you can then sort / order into how you want it. So if you would like the 3rd list item to become the first, then you simply drag and drop it to the first line.
I now have a problem in my mongoose schema. I am looking for a way to implement an order attribute or something that would allow me to add a order value such as 0 or 1 depending on the position of the lyrics. Does any of you know how to best implement such order?
Here is a copy of my schema. Currently lyrics is an array of lyric objectId's. But in there i would need an "Order" as well, so that i can sort the array according to the order value.
const mongoose = require("mongoose");
const SetlistSchema = new mongoose.Schema({
setlistName: { type: String, required: true },
lastEdited: { type: Date },
createdAt: { type: Date, default: Date.now },
lyrics: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Lyric'
}],
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
module.exports = mongoose.model("Setlist", SetlistSchema);
Here is the Lyrics schema.
const mongoose = require("mongoose");
const LyricSchema = new mongoose.Schema({
lyricName: { type: String, required: true },
lyricContent: { type: String, required: true },
lastEdited: { type: Date },
createdAt: { type: Date, default: Date.now },
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
module.exports = mongoose.model("Lyric", LyricSchema);
If adding an order number isn't the best practice, what can you then recommend as a way of keeping track of which order the user would like the lyrics to show up?
You can use aggregation framework to sort lyrics by order field. You first need to add a sort field with Number type.
Setlist.aggregate([
{
$unwind: "$lyrics"
},
{
$lookup: {
from: "lyrics", // MUST be the PHYSICAL collection name
localField: "lyrics",
foreignField: "_id",
as: "lyrics"
}
},
{
$sort: {
"lyrics.order": 1
}
},
{
"$group": {
"_id": "$_id",
"lyrics": {
"$push": "$lyrics"
},
"allFields": {
"$first": "$$ROOT"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$allFields",
{
"lyrics": "$lyrics"
}
]
}
}
}
])
Playground
Sample documents:
db={
"lists": [
{
"_id": ObjectId("5a934e000102030405000000"),
"setlistName": "list1",
"lastEdited": ISODate("2020-03-18T23:11:56.443+03:00"),
"createdAt": ISODate("2020-03-15T23:11:56.443+03:00"),
"lyrics": [
ObjectId("6a934e000102030405000000"),
ObjectId("6a934e000102030405000001"),
ObjectId("6a934e000102030405000002")
]
},
{
"_id": ObjectId("5a934e000102030405000001"),
"setlistName": "list2",
"lastEdited": ISODate("2020-03-11T23:11:56.443+03:00"),
"createdAt": ISODate("2020-03-11T23:11:56.443+03:00"),
"lyrics": [
ObjectId("6a934e000102030405000003"),
ObjectId("6a934e000102030405000004")
]
}
],
"lyrics": [
{
"_id": ObjectId("6a934e000102030405000000"),
"name": "Lyric 1",
"order": 3
},
{
"_id": ObjectId("6a934e000102030405000001"),
"name": "Lyric 2",
"order": 1
},
{
"_id": ObjectId("6a934e000102030405000002"),
"name": "Lyric 3",
"order": 2
},
{
"_id": ObjectId("6a934e000102030405000003"),
"name": "Lyric 4",
"order": 2
},
{
"_id": ObjectId("6a934e000102030405000004"),
"name": "Lyric 5",
"order": 1
}
]
}
Output: (as you see lyrics are sorted by order field value)
[
{
"_id": ObjectId("5a934e000102030405000000"),
"createdAt": ISODate("2020-03-15T20:11:56.443Z"),
"lastEdited": ISODate("2020-03-18T20:11:56.443Z"),
"lyrics": [
[
{
"_id": ObjectId("6a934e000102030405000001"),
"name": "Lyric 2",
"order": 1
}
],
[
{
"_id": ObjectId("6a934e000102030405000002"),
"name": "Lyric 3",
"order": 2
}
],
[
{
"_id": ObjectId("6a934e000102030405000000"),
"name": "Lyric 1",
"order": 3
}
]
],
"setlistName": "list1"
},
{
"_id": ObjectId("5a934e000102030405000001"),
"createdAt": ISODate("2020-03-11T20:11:56.443Z"),
"lastEdited": ISODate("2020-03-11T20:11:56.443Z"),
"lyrics": [
[
{
"_id": ObjectId("6a934e000102030405000004"),
"name": "Lyric 5",
"order": 1
}
],
[
{
"_id": ObjectId("6a934e000102030405000003"),
"name": "Lyric 4",
"order": 2
}
]
],
"setlistName": "list2"
}
]

NoSuchMethodError: The method '[]' was called on null

I am new to flutter.I am trying to get a json from api from the following code:
final response = await http.get(url, headers: {
'Content-Type': 'application/json; charset=utf-8',
});
print((json.decode(response.body)['categories'] as List)
.map((data) => CategoryModel.fromJson(data))
.toList());
final responseJson = (json.decode(response.body)['categories'] as List)
.map((data) => CategoryModel.fromJson(data))
.toList();
return responseJson;
However i can't deserialize it.
here is the error I'm getting:
I/flutter (19749): NoSuchMethodError: The method '[]' was called on null.
I/flutter (19749): Receiver: null
I/flutter (19749): Tried calling: []("products")
CategoryModel:
import 'package:pbl_store/models/cat_assoc.dart';
class CategoryModel{
String id;
String relationShipId;
String name;
String idParent;
String levelDept;
String numberProductRecursive;
String active;
CatAsso associationModel;
CategoryModel({this.id, this.name, this.idParent, this.relationShipId,
this.levelDept, this.associationModel, this.numberProductRecursive, this.active});
factory CategoryModel.fromJson(Map<String, dynamic> parsedJson) {
return CategoryModel(
id: parsedJson['id'].toString(),
name: parsedJson['name'] ,
idParent: parsedJson['id_parent'],
levelDept: parsedJson['level_depth'],
active: parsedJson['active'],
numberProductRecursive: parsedJson['nb_products_recursive'].toString(),
associationModel: CatAsso.fromJson(parsedJson['associations'])
);
}
}
ProductInCategory:
class ProductInCategory{
String id;
ProductInCategory({this.id});
factory ProductInCategory.fromJson(Map<String, dynamic> parsedJson){
return ProductInCategory(
id: parsedJson['id'].toString()
);
}
}
CatAsso:
import 'package:pbl_store/models/product_in_category.dart';
class CatAsso{
List<ProductInCategory> filterPs;
CatAsso({this.filterPs});
factory CatAsso.fromJson(Map<String, dynamic> parsedJson) {
var product = parsedJson['products'];
List<ProductInCategory> filteredProductList = List();
if(product != null){
filteredProductList = List<ProductInCategory>.from(product.map<ProductInCategory>((i) => ProductInCategory.fromJson(i)));
}
return CatAsso(
filterPs: filteredProductList
);
}
}
Inside each category, there are ID of sub category and ID of product. I want the ID of product.
here's the json I'm trying to get:
{
"categories": [
{
"id": 2,
"id_parent": "1",
"level_depth": "1",
"nb_products_recursive": "162",
"active": "1",
"id_shop_default": "1",
"is_root_category": "1",
"position": "0",
"date_add": "2018-12-31 09:52:57",
"date_upd": "2018-12-31 09:52:57",
"name": "Home",
"link_rewrite": "home",
"description": "",
"meta_title": "",
"meta_description": "",
"meta_keywords": "",
"associations": {
"categories": [
{
"id": "3"
},
{
"id": "4"
},
{
"id": "5"
}
],
"products": [
{
"id": "8"
},
{
"id": "13"
},
{
"id": "14"
},
{
"id": "17"
},
{
"id": "18"
},
{
"id": "19"
},
{
"id": "125"
},
{
"id": "126"
},
{
"id": "127"
},
{
"id": "128"
},
{
"id": "129"
},
{
"id": "130"
},
{
"id": "131"
},
{
"id": "132"
},
{
"id": "133"
},
{
"id": "134"
},
{
"id": "135"
},
{
"id": "136"
},
{
"id": "137"
},
{
"id": "138"
},
{
"id": "139"
},
{
"id": "140"
},
{
"id": "141"
},
{
"id": "142"
},
{
"id": "143"
},
{
"id": "145"
},
{
"id": "146"
},
{
"id": "147"
},
{
"id": "148"
},
{
"id": "149"
},
{
"id": "150"
},
{
"id": "151"
},
{
"id": "152"
},
{
"id": "153"
},
{
"id": "154"
},
{
"id": "156"
},
{
"id": "157"
},
{
"id": "158"
},
{
"id": "159"
},
{
"id": "160"
},
{
"id": "161"
},
{
"id": "162"
},
{
"id": "163"
},
{
"id": "164"
},
{
"id": "165"
},
{
"id": "166"
},
{
"id": "167"
},
{
"id": "168"
},
{
"id": "169"
},
{
"id": "170"
},
{
"id": "171"
},
{
"id": "172"
},
{
"id": "173"
},
{
"id": "174"
},
{
"id": "175"
},
{
"id": "178"
},
{
"id": "179"
},
{
"id": "180"
},
{
"id": "181"
},
{
"id": "182"
},
{
"id": "183"
},
{
"id": "184"
},
{
"id": "185"
},
{
"id": "186"
},
{
"id": "187"
},
{
"id": "188"
},
{
"id": "189"
},
{
"id": "190"
},
{
"id": "191"
},
{
"id": "192"
},
{
"id": "193"
},
{
"id": "195"
}
]
}
}
]
}
Please explain me why this problem occur and help me find the solution....
Try this
Future <CategoryModel> getCategories() async {
try {
final response = await http.get(url ,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
);
////print(response.body);
return categoryModelFromJson(response.body);
}on Exception catch (e){
print(e);
CategoryModel reply=CategoryModel();
return reply;
}
}
========
// To parse this JSON data, do
//
// final categoryModel = categoryModelFromJson(jsonString);
import 'dart:convert';
CategoryModel categoryModelFromJson(String str) => CategoryModel.fromJson(json.decode(str));
String categoryModelToJson(CategoryModel data) => json.encode(data.toJson());
class CategoryModel {
List<CategoryModelCategory> categories;
CategoryModel({
this.categories,
});
factory CategoryModel.fromJson(Map<String, dynamic> json) => CategoryModel(
categories: List<CategoryModelCategory>.from(json["categories"].map((x) => CategoryModelCategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"categories": List<dynamic>.from(categories.map((x) => x.toJson())),
};
}
class CategoryModelCategory {
int id;
String idParent;
String levelDepth;
String nbProductsRecursive;
String active;
String idShopDefault;
String isRootCategory;
String position;
String dateAdd;
String dateUpd;
String name;
String linkRewrite;
String description;
String metaTitle;
String metaDescription;
String metaKeywords;
Associations associations;
CategoryModelCategory({
this.id,
this.idParent,
this.levelDepth,
this.nbProductsRecursive,
this.active,
this.idShopDefault,
this.isRootCategory,
this.position,
this.dateAdd,
this.dateUpd,
this.name,
this.linkRewrite,
this.description,
this.metaTitle,
this.metaDescription,
this.metaKeywords,
this.associations,
});
factory CategoryModelCategory.fromJson(Map<String, dynamic> json) => CategoryModelCategory(
id: json["id"],
idParent: json["id_parent"],
levelDepth: json["level_depth"],
nbProductsRecursive: json["nb_products_recursive"],
active: json["active"],
idShopDefault: json["id_shop_default"],
isRootCategory: json["is_root_category"],
position: json["position"],
dateAdd: json["date_add"],
dateUpd: json["date_upd"],
name: json["name"],
linkRewrite: json["link_rewrite"],
description: json["description"],
metaTitle: json["meta_title"],
metaDescription: json["meta_description"],
metaKeywords: json["meta_keywords"],
associations: Associations.fromJson(json["associations"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"id_parent": idParent,
"level_depth": levelDepth,
"nb_products_recursive": nbProductsRecursive,
"active": active,
"id_shop_default": idShopDefault,
"is_root_category": isRootCategory,
"position": position,
"date_add": dateAdd,
"date_upd": dateUpd,
"name": name,
"link_rewrite": linkRewrite,
"description": description,
"meta_title": metaTitle,
"meta_description": metaDescription,
"meta_keywords": metaKeywords,
"associations": associations.toJson(),
};
}
class Associations {
List<ProductElement> categories;
List<ProductElement> products;
Associations({
this.categories,
this.products,
});
factory Associations.fromJson(Map<String, dynamic> json) => Associations(
categories: List<ProductElement>.from(json["categories"].map((x) => ProductElement.fromJson(x))),
products: List<ProductElement>.from(json["products"].map((x) => ProductElement.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"categories": List<dynamic>.from(categories.map((x) => x.toJson())),
"products": List<dynamic>.from(products.map((x) => x.toJson())),
};
}
class ProductElement {
String id;
ProductElement({
this.id,
});
factory ProductElement.fromJson(Map<String, dynamic> json) => ProductElement(
id: json["id"],
);
Map<String, dynamic> toJson() => {
"id": id,
};
}

How to get values in an array from nested array of objects based on a given condition?

I'm using lodash and I have the following array of objects:
[{
"id": 1,
"values": [
{
"sub": "fr",
"name": "foobar1"
},
{
"sub": "en",
"name": "foobar2"
}
]
},
{
"id": 2,
"values": [
{
"sub": "fr",
"name": "foobar3"
},
{
"sub": "en",
"name": "foobar4"
}
]
}]
What i'm trying to get the list of ID and name for a given "SUB".
So, with the previous object, if I send the sub fr I want to get:
[{
"id": 1,
"name": "foobar1"
},
{
"id": 2,
"name": "foobar3"
}]
Do you know if I can easily do it with lodash?
I tried to use _.pick but it doesn't working(I'm a bit lost with these mixes between nested objects and arrays) _.map(data, function (o) { _.pick(o, ['id', 'values.name']) });.
I also tried to use _.filter with things like _.filter(data, { values: [{ sub: 'fr' }]}); but it return all the items. What I'm looking for is to return the nested part only.
You can use flatMap() where its callback returns an array of filtered subs using filter() where each filtered item is transformed using map().
var result = _.flatMap(data, item =>
_(item.values)
.filter({ sub: 'fr' })
.map(v => ({id: item.id, name: v.name}))
.value()
);
var data = [{
"id": 1,
"values": [
{
"sub": "fr",
"name": "foobar1"
},
{
"sub": "en",
"name": "foobar2"
}
]
},
{
"id": 2,
"values": [
{
"sub": "fr",
"name": "foobar3"
},
{
"sub": "en",
"name": "foobar4"
}
]
}];
var result = _.flatMap(data, item =>
_(item.values)
.filter({ sub: 'fr' })
.map(v => ({id: item.id, name: v.name}))
.value()
);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
following #ryeballar's answer, a shorter version with map
var result = _.map(data, item => ({id: item.id, name: item.name}));