Skip to content

Instantly share code, notes, and snippets.

@umarov
Last active January 13, 2018 23:25
Show Gist options
  • Save umarov/027d0c8df2fafa78636a7c56481a7b2c to your computer and use it in GitHub Desktop.
Save umarov/027d0c8df2fafa78636a7c56481a7b2c to your computer and use it in GitHub Desktop.
TypeORM issue
import { Entity, PrimaryGeneratedColumn, OneToMany, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
import { Order } from "./Order";
@Entity()
export class Client {
@PrimaryGeneratedColumn() id: number;
@Column('character varying') name: string;
@Column('character varying') location: string;
@OneToMany(type => Order, order => order.client)
orders: Order[];
@Column()
@CreateDateColumn()
createdAt: Date;
@Column()
@UpdateDateColumn()
updatedAt: Date;
constructor(name: string, location: string) {
this.name = name;
this.location = location;
}
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
getRepository,
CreateDateColumn,
UpdateDateColumn,
OneToMany,
Index,
} from 'typeorm';
import { Order } from './Order';
@Entity()
export class Customer {
@PrimaryGeneratedColumn() id: number;
@Index()
@Column({
type: 'bigint',
unique: true,
})
phoneNumber: number;
@OneToMany(type => Order, order => order.customer)
orders: Order[];
@Column()
@CreateDateColumn()
createdAt: Date;
@Column()
@UpdateDateColumn()
updatedAt: Date;
static async findOrCreate(phoneNumber: number) {
const customerRepo = getRepository(Customer);
let customer = await customerRepo.findOne({ phoneNumber });
if (customer) return customer;
customer = new Customer();
customer.phoneNumber = phoneNumber;
return customerRepo.save(customer);
}
}
"dependencies": {
"body-parser": "^1.18.2",
"cors": "^2.8.4",
"dotenv": "^4.0.0",
"express": "^4.16.2",
"multer": "^1.3.0",
"node-fetch": "^1.7.3",
"pg": "^7.4.1",
"reflect-metadata": "^0.1.10",
"routing-controllers": "^0.7.6",
"ts-node": "^4.1.0",
"typeorm": "^0.1.11"
},
"devDependencies": {
"@types/body-parser": "^1.16.8",
"@types/dotenv": "^4.0.2",
"@types/express": "^4.11.0",
"@types/multer": "^1.3.6",
"@types/node": "^8.5.8",
"@types/node-fetch": "^1.6.7",
"nodemon": "^1.14.11",
"ts-node": "4.1.0",
"tslint": "^5.9.1",
"typescript": "^2.6.2"
}
const customerRepo = getRepository(Customer);
const orderRepo = getRepository(Order);
const clientRepo = getRepository(Client);
const [customer, client, orders] = await Promise.all([
clientRepo.findOne(),
customerRepo.findOne(),
orderRepo.find({ relations: ['client', 'customer', 'orderItems'] })
]);
console.log('\n\nAll orders ');
console.log(orders); // []
console.log('\n\nIDs ');
console.log(customer.id); // 1
console.log(client.id); // 1
const order = new Order(0, client, customer, []);
order.status = 'cancelled';
await orderRepo.save(order);
console.log('\n\nFirst active order ');
console.log(
await orderRepo.findOne({
relations: ['customer', 'client', 'orderItems'],
status: 'active',
customerId: customer.id
})
);
/**
* Order {
orderTotal: 0,
status: 'cancelled',
customer:
Customer {
id: 1,
phoneNumber: 'REDACTED',
createdAt: 2018-01-13T03:38:34.122Z,
updatedAt: 2018-01-13T03:38:34.122Z },
client:
Client {
name: 'REDACTED',
location: 'REDACTED',
id: 1,
createdAt: 2018-01-13T03:38:24.502Z,
updatedAt: 2018-01-13T03:38:24.502Z },
orderItems: [],
id: 23,
createdAt: 2018-01-13T22:57:59.753Z,
updatedAt: 2018-01-13T22:57:59.753Z }
*/
console.log('With query builder');
console.log(
await getConnection()
.createQueryBuilder()
.from(Order, 'o')
.where('o."status" = :status', {
status: 'active'
})
.andWhere('o."customerId" = :customerId', {
customerId: customer.id
})
.getOne()
);
// Undefined
console.log('With query builder using setParameter');
console.log(
await getConnection()
.createQueryBuilder()
.from(Order, 'o')
.where('o."status" = :status')
.setParameter('status', 'active')
.andWhere('o."customerId" = :customerId')
.setParameter('customerId', customer.id)
.getOne()
);
// Undefined
const testClient = new Client('Test client', 'Somewhere');
const testCustomer = new Customer();
testCustomer.phoneNumber = Math.floor(Math.random() * 1000000000);
await Promise.all([customerRepo.save(testCustomer), clientRepo.save(testClient)]);
const testOrder = new Order(100, testCustomer, testClient, []);
console.log(testOrder.status); // Prints inactive
await orderRepo.save(testOrder);
console.log('\n\nTest order ');
console.log(testOrder);
/**
* Order {
orderTotal: 100,
status: 'inactive',
customer:
Customer {
phoneNumber: 832888444,
id: 23,
updatedAt: 2018-01-13T22:59:16.232Z,
createdAt: 2018-01-13T22:59:16.232Z },
client:
Client {
name: 'Test client',
location: 'Somewhere',
id: 22,
updatedAt: 2018-01-13T22:59:16.232Z,
createdAt: 2018-01-13T22:59:16.232Z },
orderItems: [],
id: 26,
updatedAt: 2018-01-13T22:59:16.235Z,
createdAt: 2018-01-13T22:59:16.235Z }
*/
console.log('\n\nAll active orders ');
console.log(
await orderRepo.find({
relations: ['customer', 'client', 'orderItems'],
status: 'active',
customerId: testCustomer.id
})
);
/**
* [ Order {
orderTotal: 0,
status: 'cancelled',
customer:
Customer {
id: 1,
phoneNumber: '17033860164',
createdAt: 2018-01-13T03:38:34.122Z,
updatedAt: 2018-01-13T03:38:34.122Z },
client:
Client {
name: 'Trap',
location: 'California',
id: 1,
createdAt: 2018-01-13T03:38:24.502Z,
updatedAt: 2018-01-13T03:38:24.502Z },
orderItems: [],
id: 25,
createdAt: 2018-01-13T22:59:16.216Z,
updatedAt: 2018-01-13T22:59:16.216Z },
Order {
orderTotal: 100,
status: 'inactive',
customer:
Customer {
id: 23,
phoneNumber: '832888444',
createdAt: 2018-01-13T22:59:16.232Z,
updatedAt: 2018-01-13T22:59:16.232Z },
client:
Client {
name: 'Test client',
location: 'Somewhere',
id: 22,
createdAt: 2018-01-13T22:59:16.232Z,
updatedAt: 2018-01-13T22:59:16.232Z },
orderItems: [],
id: 26,
createdAt: 2018-01-13T22:59:16.235Z,
updatedAt: 2018-01-13T22:59:16.235Z } ]
*/
console.log('With query builder');
console.log(
await getConnection()
.createQueryBuilder()
.from(Order, 'o')
.where('o."status" = :status', {
status: 'active'
})
.getMany()
);
// []
console.log('With query builder using setParameter');
console.log(
await getConnection()
.createQueryBuilder()
.from(Order, 'o')
.where('o."status" = :status')
.setParameter('status', 'active')
.getMany()
);
// []
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
OneToMany,
ManyToOne,
Index
} from 'typeorm';
import { Customer } from './Customer';
import { OrderItem } from './OrderItem';
import { formatPrice } from '../../helpers/moneyFormatter';
import { Client } from './Client';
export enum OrderStatuses {
inactive = 'inactive',
active = 'active',
ordered = 'ordered',
ondelivery = 'ondelivery',
delivered = 'delivered',
removed = 'removed',
cancelled = 'cancelled'
}
@Entity()
export class Order {
@PrimaryGeneratedColumn() id: number;
@Column('int') orderTotal: number;
@Column('character varying')
@Index()
status: string;
@ManyToOne(type => Customer, customer => customer.orders)
customer: Customer;
@ManyToOne(type => Client, client => client.orders)
client: Client;
@OneToMany(type => OrderItem, orderItem => orderItem.order)
orderItems: OrderItem[];
@Column()
@CreateDateColumn()
createdAt: Date;
@Column()
@UpdateDateColumn()
updatedAt: Date;
constructor(orderTotal: number, customer: Customer, orderItems: OrderItem[]) {
this.orderTotal = orderTotal;
this.status = OrderStatuses.inactive;
this.customer = customer;
this.orderItems = orderItems;
}
update(orderTotal: number, status: string, customer: Customer, orderItems: OrderItem[]) {
this.orderTotal = orderTotal;
this.status = status;
this.customer = customer;
this.orderItems = orderItems;
}
toStringOrderItems() {
return this.orderItems.map((item, index) => `${index + 1 }: ${item.toString()}\n`).join('')
}
toString() {
return `Order ID${this.id} with status of ${this.status} and total of ${formatPrice(
this.orderTotal
)} with order items of ${this.toStringOrderItems()}\n`;
}
static nonAvailableStatuses = [
OrderStatuses.inactive,
OrderStatuses.cancelled,
OrderStatuses.removed
];
static availableStatuses = [
OrderStatuses.active,
OrderStatuses.ordered,
OrderStatuses.ondelivery,
OrderStatuses.delivered
];
}
getActiveOrder(customer: Customer, client: Client) {
return getConnection()
.createQueryBuilder()
.select()
.from(Order, 'order')
.where(
'"order".status IN (:statuses) AND "order"."clientId" = :clientId AND "order"."customerId" = :customerId',
{
statuses: Order.availableStatuses,
clientId: client.id,
customerId: customer.id
}
).getOne();
}
// Expected: All the orders with 'active', 'ordered', 'ondelivery', and 'delivered' status.
// Actual: Resolves to an empty array
getActiveOrder(customer: Customer, client: Client) {
return getConnection()
.createQueryBuilder()
.select()
.from(Order, 'order')
.where(
'"order".status = :status AND "order"."clientId" = :clientId AND "order"."customerId" = :customerId',
{
status: OrderStatuses.active,
clientId: client.id,
customerId: customer.id
}
).getOne();
}
// Expect: Order object, which has the active status.
// Actual: Resolves to undefined
getActiveOrder(customer: Customer, client: Client) {
return getRepository(Order).findOne({
relations: ['customer', 'client', 'orderItems'],
clientId: client.id,
customerId: customer.id,
status: Order.availableStatuses
});
}
// DB already has ONE order which has the status of 'ordered'
// Expected: Array of one order which has the status of ordered
// Actual: Resolves to the Order which has the status of 'ordered'. status: 'active' is ignored
getActiveOrder(customer: Customer, client: Client) {
return getRepository(Order).findOne({
relations: ['customer', 'client', 'orderItems'],
clientId: client.id,
customerId: customer.id,
status: 'active'
});
}
// DB already has ONE order which has the status of 'ordered'
// Expected: Undefined
// Actual: Resolves to the Order which has the status of 'ordered'. status: 'active' is ignored
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment