Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
175
rated 0 times [  177] [ 2]  / answers: 1 / hits: 13874  / 10 Years ago, mon, april 28, 2014, 12:00:00

I'm having the following 3 files.



user.js requires room.js and room.js requires user.js.



user.js



var Room = require('./room.js');

var User = function () {};
User.prototype.test = function () {
return new Room();
};

module.exports = User;


room.js



var User = require('./user.js');

var Room = function () {};
Room.prototype.test = function () {
return new User();
};

module.exports = Room;


index.js



var User = require('./user.js');
var Room = require('./room.js');

var user = new User();
var room = new Room();

user.test();
room.test();


index.js requires both room and user.



Here's the problem. When I run index.js, I will get a TypeError from 'new User()' in room.js. It seems that User in room.js is hidden by the User in index.js.



Am I doing anything wrong? Is this kind of requiring allowed? Any ideas? Thanks.


More From » node.js

 Answers
5

Check out http://nodejs.org/api/modules.html#modules_cycles for how this is handled in node.



You can solve your problem in several ways, for example passing in the dependencies to the instances aka Dependency Injection



// user.js
var User = function (Room) { this.Room = Room; };
User.prototype.test = function () {
return new this.Room();
};
module.exports = User;

// room.js
var Room = function (User) { this.User = User; };
Room.prototype.test = function () {
return new this.User();
};
module.exports = Room;

// index.js
var User = require('./user.js');
var Room = require('./room.js');

var user = new User(Room);
var room = new Room(User);


Another way would be to require the files only when you need them



// user.js
var User = function () {};
User.prototype.test = function () {
var Room = require('./room');
return new Room();
};
module.exports = User;


// room.js
var Room = function () {};
Room.prototype.test = function () {
var User = require('./user');
return new User();
};
module.exports = Room;

// index.js
var User = require('./user.js');
var Room = require('./room.js');

var user = new User();
var room = new Room();


Like this, your exports are defined by the time you need them.



But generally, if you have circular dependencies, you are doing something wrong and should think about your architecture.
If a User needs to create new Rooms and a Room needs to create new Users, it seems like they both have too much responsibility.
Possibly you would want a third component which is responsible for creating and passing the right instances to the Room and User, instead of having them instantiate those directly.


[#45708] Saturday, April 26, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
yosefleod

Total Points: 113
Total Questions: 100
Total Answers: 115

Location: Egypt
Member since Tue, May 3, 2022
2 Years ago
;