Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS: how to implement repository pattern

I would like to implement the Repository pattern in my NodeJS app, but I'm running into troubles with circular requires (I guess...).

How I'm trying to implement it:

  • PersonRepository class with methods: getAll, getById, create, update, delete
  • Person class with methods: init, createAccount, showRelations, addRelation,

First of all: Is my repository pattern design correct?

My classes:

personRepository.js

const PersonModel = require('./model');
const Person = require('./person');

class PersonRepository {

    constructor() {
        this._persons = new Set();
    }

    getAll( cb ) { // To Do: convert to promise
        let results = new Set();

        PersonModel.find({}, 'firstName lastName', (err, people) => {
            if (err) { 
                console.error(err);
            }
            people.forEach((person, index) => {
                let foundPerson = new Person(person._id.toString(), person.firstName, person.lastName, person.email, person.birthday);
                results.add(foundPerson);
            });
            this._persons = results;
            if (cb) cb(this._persons);
        });
    }

    getById(id) {

        return PersonModel.findOne({ _id: id });

    }

    getByEmail(email) {
        throw new Error("Method not implemented");
    }

    create( person ) {
        throw new Error("Method not implemented");
    }

    update ( person ) {
        throw new Error("Method not implemented");
    }

    delete ( person ) {
        throw new Error("Method not implemented");
    }
}

module.exports = new PersonRepository();

person.js

const PersonModel = require('./model');
const personRepository = require('./personRepository');

class Person {

    constructor(personId, first, last, email, birthday) {
        this._id = personId ? personId : undefined;
        this._firstName = first ? first : undefined;
        this._lastName = last ? last : undefined;
        this._email = email ? email : undefined;
        this._birthday = birthday ? new Date(birthday) : undefined;
        this._relations = new Map();
    }
    init() { // Get all data from database
        personRepository.getById(this._id)
            .then(console.log)
            .catch(console.error);
    }

}

module.exports = Person;

tests.js

console.log("--- GET ALL : results--- ");
personRepository.getAll( (persons) => {
    for (let person of persons) {
        person.loadAllData()
            .then(() => {
                console.log(person);
            })
            .catch((e) => {
                console.log(e);
            });
    }

});
console.log("--- INIT : results--- ");
var personInit = new Person("59c18a9029ef510012312995");
console.log("before init");
console.log(personInit);
personInit.init();
console.log("after init");
console.log(personInit);

Problem: When running the "Get all" test (without the INIT tests), it works. When I add the INIT tests, I get the error:

personRepository.getById(this._id)
                         ^

TypeError: personRepository.getById is not a function
    at Person.init

How can I prevent this from happening? - Change the way I require my modules? - Change my design? (eg. don't require Person class in personRepository and just create a Set of ids in "getAll" instead of a Set of persons) - Other ideas?

Thanks for helping me! I'm trying to solve this for hours now...

like image 809
bits Avatar asked May 29 '18 19:05

bits


People also ask

How do you implement a repository pattern in node JS?

We need in root of project, create a Index. ts file, that call all repositories. You need to transpile your Typescript to Javascript files, running the tsc command from terminal, you have now in lib folder all javascript files and now, you can run your application with node lib/Index. js.

Why do we implement a repository pattern?

The Repository pattern makes it easier to test your application logic. The Repository pattern allows you to easily test your application with unit tests. Remember that unit tests only test your code, not infrastructure, so the repository abstractions make it easier to achieve that goal.

What is DTO in node JS?

//Dto data transfer object protect your API clients from changes made on the server //using function base approach function userDto(user, postsCount){ return { id:user. _id name: user.name, email: user.

What is the benefit of repository pattern in Entity Framework?

The Repository Pattern allows us to create an abstraction layer between the data access layer and the business logic layer of an application. So, this Data Access Pattern offers a more loosely coupled approach to data access.


1 Answers

Solved it myself. The problem was a circular dependency between the 2 modules. Problem is fixed by moving the requires after the module.exports.

Reference: https://coderwall.com/p/myzvmg/circular-dependencies-in-node-js

like image 54
bits Avatar answered Oct 23 '22 05:10

bits