I am trying to query and a mutation in graph QL with express-graphql, node, and mongodb. For both the query and mutation I am getting "Cannot read property 'collection' of undefined". I go into the DB and there is a collection with documents in there. The context is there to add auth later on. I have tried multiple variations of naming the collection over the past 2 days without success. Do I need to declare a const? What am I missing?
Server.js
const express = require('express');
const graphqlHTTP = require('express-graphql');
const schema = require('./graphql/schema')
const mongoose1 = require('./mongoDB')
const expressPlayground = require('graphql-playground-middleware-express').default;
const cors = require('cors')
const Event = require('./models/events')
const app = express();
app.use(cors())
app.use(express.json());
// DB
const context = async () => {
const db = await mongoose1;
return { db };
};
// Provide resolver functions for your schema fields
const resolvers = {
events: async (_, context) => {
const { db } = await context();
return db
.collection('events')
.find()
.toArray();
},
event: async ({ _id }, context) => {
const { db } = await context();
return db.collection('events').findOne({ _id });
},
createEvent: args => {
const event = new Event({
title: args.eventInput.title,
description: args.eventInput.description,
})
return event.save().then(res => {
console.log(res);
return { ...res._doc }
}).catch(err => {
console.log(err)
throw err
});
}
}
app.use(
"/graphql",
graphqlHTTP({
schema,
rootValue: resolvers,
context,
})
);
app.get('/playground', expressPlayground({ endpoint: '/graphql' }))
app.listen(5000);
console.log(`🚀 Server ready at http://localhost:5000/graphql`);
DB
require('dotenv').config()
const mongoose = require('mongoose');
const db = process.env.MONGODB
const mongoose1 = mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
module.exports = mongoose1
Schema
const { buildSchema } = require('graphql');
// Construct Schema
const schema = buildSchema(`
type Event {
_id: ID!
title: String!
description: String
date: String
}
input EventInput {
title: String!
description: String
date: String
}
type Query {
events: [Event!]!
event(_id: String!): Event!
}
type Mutation {
createEvent(eventInput: EventInput): Event
}
`);
module.exports = schema
Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const eventSchema = new Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
})
module.exports = mongoose.model('Event', eventSchema)
The function that mongoDB.js
exports returns a Promise, but that Promise resolves to undefined
because console.log
returns undefined. Since connect
should resolve to the value of the Mongoose
instance that called it, either remove the then
call entirely or else make sure you return the Mongoose
instance inside it.