Comments (3)
After many hours I could find a way to get a relational query running.
I am not sure if this is approprioate way, so please indicate if I am doing something against the idea!
First I figured out that in Bookshelf always a hasMany is declared for the opposite direction of belongsTo.
This always gave errors within User.ts until I created a collection of Pets out of Pet.
What did I do in particular:
1 new resource Owner
creating a new resource owner should give me the assignemnt of user to the pet
npm run console make:resource Owner
without migration, but with IoC
2 OwnerController.ts
delete everything what is CRUD, hence we are only querying
`
import { inject, named } from 'inversify';
import { controller, httpGet, response, requestParam } from 'inversify-express-utils';
import { Types, Targets } from '../../constants';
import { app } from '../../app';
import { OwnerService } from '../services/OwnerService';
// Get middlewares
const authenticate = app.IoC.getNamed<interfaces.Middleware>(Types.Middleware, Targets.Middleware.AuthenticateMiddleware);
@controller('/owners', authenticate.use)
export class OwnerController {
constructor( @inject(Types.Service) @named(Targets.Service.OwnerService) private ownerService: OwnerService) { }
@httpGet('/')
public async findAll( @response() res: myExpress.Response): Promise<any> {
const owners = await this.ownerService.findAll();
return res.found(owners.toJSON());
}
@httpGet('/:id')
public async findOne( @response() res: myExpress.Response, @requestParam('id') id: string): Promise<any> {
const owner = await this.ownerService.findOne(parseInt(id, 10));
return res.found(owner.toJSON());
}
// Implement your routes here
}
`
OwnerRepository.ts
delete everything related to CRUD
`
import { inject, named } from 'inversify';
import { Types, Targets } from '../../constants';
import { Owner } from '../models/Owner';
import { Pet } from '../../api/models/Pet';
import { Pets } from '../../api/models/Pets';
export class OwnerRepository {
constructor(
@inject(Types.Model) @named(Targets.Model.Owner) public OwnerModel: typeof Owner,
@inject(Types.Model) @named(Targets.Model.Pets) public PetsModel: typeof Pets
) { }
public async findAll(): Promise<Pet> {
return this.PetsModel.fetchAllPet();
}
public async findOne(id: number): Promise<Pet> {
return this.OwnerModel.fetchById(id);
}
}
`
OwnerService.ts
delete everything related to CRUD
`
import { inject, named } from 'inversify';
import { Logger as LoggerType } from '../../core/Logger';
import { Types, Core, Targets } from '../../constants';
import { NotFoundException } from '../exceptions/NotFoundException';
import { OwnerRepository } from '../repositories/OwnerRepository';
import { Owner } from '../models/Owner';
import { Pet } from '../../api/models/Pet';
export class OwnerService {
public log: LoggerType;
constructor(
@inject(Types.Repository) @named(Targets.Repository.OwnerRepository) public ownerRepo: OwnerRepository,
@inject(Types.Core) @named(Core.Logger) public Logger: typeof LoggerType
) {
this.log = new Logger(__filename);
}
public async findAll(): Promise<Pet> {
return this.ownerRepo.findAll();
}
public async findOne(id: number): Promise<Owner> {
const owner = await this.ownerRepo.findOne(id);
if (owner === null) {
this.log.warn(`Owner with the id=${id} was not found!`);
throw new NotFoundException(id);
}
return owner;
}
}
`
User.ts
adding the following:
`
import { Pets } from '../../api/models/Pets';
import { Pet } from '../../api/models/Pet';
public pet(): Pets {
return this.hasMany(Pet);
}
`
Owner.ts
delete all things what relates to table, add the fetchById method
(maybe this can be also included into Pet.ts with a different name, hence here nothing releates to Owner)
`
import { Bookshelf } from '../../config/Database';
import { Pet } from '../../api/models/Pet';
export class Owner extends Bookshelf.Model {
public static async fetchById(value: number): Promise<Pet> {
return await Pet.where<Pet>({ id: value }).fetch({withRelated: ['user']});
}
}
`
Pets.ts
create new file Pets.ts with following:
`
import { Bookshelf } from '../../config/Database';
import { Pet } from '../../api/models/Pet';
import { User } from '../../api/models/User';
export class Pets extends Bookshelf.Collection {
public static async fetchAllPet(): Promise<Pet> {
return await User.forge<Pet>().fetch({withRelated: ['pet']});
}
}
`
result
http://localhost:3000/api/owners can be called
- it gives only the first record of the user table (and if there the user has pets assigned, they are comming along)
- it does not provide all user records and their pets!
- if I change "return await Pet.forge({id: 2 }).fetch({withRelated: ['user']});" then the user with id=2 and all his pets are listed
http://localhost:3000/api/owners/3 can be called
- it provides the user with id=3 and his pets
- if I change in Owner. ts "return await Pet.forge({id: 2 }).fetch({withRelated: ['user']});" it gives the same result
conclusion
- it worked somehow for single users but not a query to all users and their pets
- I thought forge should do that?! but fetchAll can not be used with .fetch(withRelated)???
- I am still stuck in understanding how to make it right and put the things together and need HELP
from express-typescript-boilerplate.
After more hours I could resolve the relational query.
I am not sure if this is approprioate way, so please indicate if I am doing something against the idea!
What did I do in particular:
1 new resource Owner
creating a new resource owner should give me the assignemnt of user to the pet
npm run console make:resource Owner
without migration, but with IoC
2 OwnerController.ts
delete everything what is CRUD, hence we are only querying
`
import { inject, named } from 'inversify';
import { controller, httpGet, response, requestParam } from 'inversify-express-utils';
import { Types, Targets } from '../../constants';
import { app } from '../../app';
import { OwnerService } from '../services/OwnerService';
// Get middlewares
const authenticate = app.IoC.getNamed<interfaces.Middleware>(Types.Middleware, Targets.Middleware.AuthenticateMiddleware);
@controller('/owners', authenticate.use)
export class OwnerController {
constructor( @inject(Types.Service) @named(Targets.Service.OwnerService) private ownerService: OwnerService) { }
@httpGet('/')
public async findAll( @response() res: myExpress.Response): Promise<any> {
const owners = await this.ownerService.findAll();
return res.found(owners.toJSON());
}
@httpGet('/:id')
public async findOne( @response() res: myExpress.Response, @requestParam('id') id: string): Promise<any> {
const owner = await this.ownerService.findOne(parseInt(id, 10));
return res.found(owner.toJSON());
}
// Implement your routes here
}
`
OwnerRepository.ts
deleted everything which relates to CRUD
`
import { inject, named } from 'inversify';
import { Types, Targets } from '../../constants';
import { Owner } from '../models/Owner';
import { Pet } from '../../api/models/Pet';
import { Pets } from '../../api/models/Pets';
export class OwnerRepository {
constructor(
@inject(Types.Model) @named(Targets.Model.Pets) public OwnerModel: typeof Pets,
@inject(Types.Model) @named(Targets.Model.Pet) public PetModel: typeof Pet
) { }
public async findAll(): Promise<Pets> {
return this.PetModel.fetchAllPet();
}
public async findOne(id: number): Promise<Pet> {
return this.PetModel.fetchPetByUserId(id);
}
}
`
OwnerService.ts
deleted everything which relates to CRUD
`
import { inject, named } from 'inversify';
import { Logger as LoggerType } from '../../core/Logger';
import { Types, Core, Targets } from '../../constants';
import { NotFoundException } from '../exceptions/NotFoundException';
import { OwnerRepository } from '../repositories/OwnerRepository';
import { Owner } from '../models/Owner';
import { Pet } from '../../api/models/Pet';
import { Pets } from '../../api/models/Pets';
export class OwnerService {
public log: LoggerType;
constructor(
@inject(Types.Repository) @named(Targets.Repository.OwnerRepository) public ownerRepo: OwnerRepository,
@inject(Types.Core) @named(Core.Logger) public Logger: typeof LoggerType
) {
this.log = new Logger(__filename);
}
public async findAll(): Promise<Pets> {
return this.ownerRepo.findAll();
}
public async findOne(id: number): Promise<Pet> {
const owner = await this.ownerRepo.findOne(id);
if (owner === null) {
this.log.warn(`Owner with the id=${id} was not found!`);
throw new NotFoundException(id);
}
return owner;
}
}
`
User.ts
adding the following:
`
import { Pets } from '../../api/models/Pets';
import { Pet } from '../../api/models/Pet';
public pet(): Pets {
return this.hasMany(Pet);
}
`
Pet.ts
add the custom functions
`
public static async fetchPetByUserId(value: number): Promise {
return await User.where({ id: value }).fetch({withRelated: ['pet']});
}
public static async fetchAllPet(): Promise<Pets> {
// return await Pet.forge<Pet>().fetchAll({withRelated: ['user']}); // lists all pets with user,
return await User.forge<Pet>().fetchAll({withRelated: ['pet']}); // lists all user with their pets
}
`
Owner.ts
deleted this file
Pets.ts
create new file Pets.ts which creates a collection from the model
`
import { Bookshelf } from '../../config/Database';
import { Pet } from '../../api/models/Pet';
export class Pets extends Bookshelf.Collection {
}
`
result
http://localhost:3000/api/owners can be called
- it provides all user records and their pets
http://localhost:3000/api/owners/3 can be called
- it provides the user with id=3 and his pets
conclusion
- I am a bit further, but am I right?
from express-typescript-boilerplate.
Hi,
Looks oaky for me. You could also just add the pets as a collection to the user queries.
from express-typescript-boilerplate.
Related Issues (20)
- Docker build fails HOT 2
- Seeding out of date
- File upload using multer integration
- Errors when installing on Ubuntu 18 LTS HOT 2
- How can i integrate JWT Authentication in this boiler plate HOT 1
- How can i integrate JWT Authentication in this boiler plate HOT 2
- Error when installing (bcrypt) HOT 1
- Error connecting to PostgreSQL with SSL
- error while yarn run setup command HOT 5
- Integrate with Relative Path
- How to set Elastic search Loader?
- About public route without authentication
- Update version of bcrypt and sqlite3 to 5.0.1 and 5.0.0 respectively HOT 8
- How to use winston?
- Why use CommonJS?
- 'yarn start serve' does not start the server HOT 1
- Bcrypt installation errors on M1 Mac HOT 4
- docker not started nps not found
- Cannot create migrations
- Witch branch Should I use ?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from express-typescript-boilerplate.