Search code examples
javascriptknex.jssoftware-quality

What is the best way to mutualize code between both methods


I wonder what is the best solution to mutualize code between these 2 methods in javascript:

async getAllActiveRooms(ctx: ?ContextType): Promise<RoomType[]> {
    //log getAllActiveRooms
    return this.i.knex('users_rooms')
        .transacting(ctx ? ctx.transaction : null)
        .leftJoin('rooms', 'users_rooms.roomId', 'rooms.id')
        .select('rooms.*')
        .where('active', true);
}
async getActiveRoomsBySessionId(ctx: ?ContextType, sessionId: number): Promise<RoomType[]> {
    //log getAllActiveRooms
    return this.i.knex('users_rooms')
        .transacting(ctx ? ctx.transaction : null)
        .leftJoin('rooms', 'users_rooms.roomId', 'rooms.id')
        .select('rooms.*')
        .where('active', true)
        .andWhere('sessionId',sessionId)
}

Thank you


Solution

  • You can reuse getAllActiveRooms by changing its return type to knex's QueryBuilder which extends Bluebird's promise interface. You will lose the RoomType[] promise payload type though since it extends Bluebird<any>

    From knex's latest type definition (QueryBuilder extends ChainableInterface):

    interface QueryBuilder extends QueryInterface, ChainableInterface {
            or: QueryBuilder;
            and: QueryBuilder;
    
            //TODO: Promise?
            columnInfo(column?: string): Bluebird<ColumnInfo>;
    
            forUpdate(): QueryBuilder;
            forShare(): QueryBuilder;
    
            toSQL(): Sql;
    
            on(event: string, callback: Function): QueryBuilder;
    }
    
    interface ChainableInterface extends Bluebird<any> {
            toQuery(): string;
            options(options: any): QueryBuilder;
            stream(callback: (readable: stream.PassThrough) => any): Bluebird<any>;
            stream(options?: { [key: string]: any }): stream.PassThrough;
            stream(options: { [key: string]: any }, callback: (readable: stream.PassThrough) => any): Bluebird<any>;
            pipe(writable: any): stream.PassThrough;
            exec(callback: Function): QueryBuilder;
    }
    

    async getAllActiveRooms(ctx: ?ContextType): QueryBuilder {
        //log getAllActiveRooms
        return this.i.knex('users_rooms')
            .transacting(ctx ? ctx.transaction : null)
            .leftJoin('rooms', 'users_rooms.roomId', 'rooms.id')
            .select('rooms.*')
            .where('active', true);
    }
    async getActiveRoomsBySessionId(ctx: ?ContextType, sessionId: number): Promise<RoomType[]> {
        //log getAllActiveRooms
        return this.getAllActiveRooms(ctx)
            .andWhere('sessionId',sessionId)
    }