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:
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...
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.
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.
//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.
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.
Solved it myself. The problem was a circular dependency between the 2 modules. Problem is fixed by moving the require
s after the module.exports
.
Reference: https://coderwall.com/p/myzvmg/circular-dependencies-in-node-js
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With