Splitting up the resolvers index.js from branch/video #6, into folders like user.js and event.js causes a circular dependency, since users requires logic from events, and visa versa.
How do you solve these kind of circular dependency issues when different models and their "Polulators" require one another?
(getUserById => getEventsById => getUserById => getEventsById => ...)
file: user.jsWarning: Accessing non-existent property 'getEventsById' of module exports inside circular dependencycreatedEvents: getEventsById(createdEvents) => TypeError: getEventsById is not a function
// @ts-check
const { User } = require('../models');
const { hash } = require('bcryptjs');
const { getEventsById } = require('./event');
module.exports = {
// Poplulators
getUserById: async (userID) => {
try {
const {
_doc: { createdEvents, ...rest }
} = await User.findById(userID);
return {
createdEvents: getEventsById(createdEvents),
...rest
};
} catch (error) {
throw error;
}
},
// Resolvers
users: async () => {
try {
const users = await User.find();
return users.map(({ _doc: { password, createdEvents, ...rest } }) => {
return {
password: null, // Security: Hide user password in result
createdEvents: getEventsById(createdEvents), // populate the user.createdEvents field with Event data
...rest
};
});
} catch (error) {
throw error;
}
},
user: async ({ email }) => {
try {
const {
_doc: { password, createdEvents, ...rest }
} = await User.findOne({ email: email });
return {
password: null,
createdEvents: getEventsById(createdEvents),
...rest
};
} catch (error) {
throw error;
}
},
createUser: async ({ userInput: { email, password } }) => {
try {
// Check if user already exists
const foundUser = await User.findOne({ email: email });
// User with email found
if (foundUser) {
throw new Error('User already exists');
}
// New user
// Security: Hash user password
const hashedPassword = await hash(password, 12);
// Create a new MongoDB user model with data
const user = new User({
email: email,
password: hashedPassword
});
// Save user to MongoDB and return result
const { email: userEmail, password: userPassword } = await user.save();
// Security: Hide user password in result
return { email: userEmail, password: null };
} catch (error) {
throw error;
}
}
};
file: event.jsWarning: Accessing non-existent property 'getUserById' of module exports inside circular dependencycreator: getUserById(creator) => TypeError: getUserById is not a function
// @ts-check
const { User, Event } = require('../models');
const { getUserById } = require('./user');
module.exports = {
// Poplulators
getEventsById: async (eventIDs) => {
try {
const events = await Event.find({ _id: { $in: eventIDs } });
return events.map(({ _doc: { creator, date, ...rest } }) => {
return {
date: new Date(date).toISOString(),
creator: getUserById(creator),
...rest
};
});
} catch (error) {
throw error;
}
},
// Resolvers
events: async () => {
try {
const events = await Event.find();
return events.map(({ _doc: { creator, date, ...rest } }) => {
return {
date: new Date(date).toISOString(),
creator: getUserById(creator),
...rest
};
});
} catch (error) {
throw error;
}
},
createEvent: async ({ eventInput: { title, description, price, date } }) => {
// Create a new MongoDB event model with data
const event = new Event({
title: title,
description: description,
price: +price,
date: new Date(date),
creator: '60ecc8c9b01258b09dc23aa8'
});
// eventDate temp store
let storedEvent;
// Save event to MongoDB and return result
// Add event to user.createdEvents
try {
const { _doc: eventData } = await event.save();
// Store even data
// Reference Event creator to User
storedEvent = {
...eventData,
date: new Date(eventData.date).toISOString(),
creator: getUserById(eventData.creator)
};
// Find creator
// To add event to user.createdEvents
const foundUser = await User.findById(eventData.creator);
// no User found
if (!foundUser) {
throw new Error('No user found');
}
// Add event _id to user.createdEVents
foundUser.createdEvents.push(eventData._id);
// Save (same as update) user
await foundUser.save();
// return the stored event
return storedEvent;
} catch (error) {
throw error;
}
}
};
Thanks a lot for the free course.
Splitting up the resolvers index.js from branch/video #6, into folders like user.js and event.js causes a circular dependency, since users requires logic from events, and visa versa.
How do you solve these kind of circular dependency issues when different models and their "Polulators" require one another? (getUserById => getEventsById => getUserById => getEventsById => ...)
file: user.js
Warning: Accessing non-existent property 'getEventsById' of module exports inside circular dependency
createdEvents: getEventsById(createdEvents) => TypeError: getEventsById is not a function
file: event.js
Warning: Accessing non-existent property 'getUserById' of module exports inside circular dependency
creator: getUserById(creator) => TypeError: getUserById is not a function