Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What is the best method (if there is one) to import a set of functions in a module?

I am trying to solve this:

I have a module, let’s say "users", for which I have a service with basic database operations (find, findMany, save etc).

I want to create more modules which all have the same basic database operations but I don’t want to have to write them all again

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

To make things easy, I have these 2 functions in an utils file:

export async function find<T extends Model>(model: T, query, options?): Promise<T> {
    return model.find(query)
}

and

export async function findOne<T extends Model>(model: T, query, options?): Promise<T> {
    return model.findOne(query)
}

How can I make it so I import each of this functions to a class (using TypeScript decorators or other TS magic)

I want to have something like this

import { attachAllBasicDatabaseMethods } from "./model-utils/operations"
export class UserController {
    @attachAllBasicDatabaseMethods()
    private constructor() {}
}

so in my controller i can use a method like this:

async getSomeUsers() {
    const users = await this.findMany(UserModel, this.query, this.options);
    return users;
}

The decorator idea is just something I have thought of, but I know there are some other methods of solving this

Or better: using that decorator with the model as the parameter automatically binds the model to the methods, so I can use this.find(this.query, this.options)

>Solution :

You could indeed do this with decorators. You could even make the decorators accept the model so you don’t need to specify it on each call to find/findOne:

Here’s a rough example:

import { find, findAll } from "./somewhere";
function attachAllBasicDatabaseMethods<T extends Model>(model: T) {
    return function(target: any) {
        Object.defineProperty(target.prototype, "find", {
            value(query: any, options?: any): T { // TODO: Appropriate types for params
                return find(model, query, options);
            },
            writable: true,
            configurable: true,
        });
        Object.defineProperty(target.prototype, "findAll", {
            value(query: any, options?: any): T { // TODO: Appropriate types for params
                return findAll(model, query, options);
            },
            writable: true,
            configurable: true,
        });
    };
}

Usage:

@attachAllBasicDatabaseMethods(UserModel)
class UserController {
    // ...
}

That’s an example of a decorator factory. I made it a factory so that it could accept the model as a parameter and "bake it" into the find/findAll methods.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading