When attempting to run the following query I get this error: "Cannot return null for non-nullable field User.first_name.". I am not expecting a null result.
Query:
{
site(site_reference: 123456789) {
site_name
site_managers {
_id
first_name
}
}
}
What I expect to see is:
{
"data": {
"site": {
"site_name": "Test Site",
"site_managers": [
{
"_id": "5bbcd55ff7bd643be4d490fa",
"first_name": "Claire"
},
{
"_id": "5b9fa2e1f66fb32164f4d547",
"first_name": "John"
}
]
}
}
}
My MongoDB stores the _id in an array which it is able to return, however anything else from my user type returns null.
User Schema:
type User {
_id: String!,
first_name: String!,
last_name: String!,
role_id: Int!
email: String!,
password: String,
created_date: String!,
updated_date: String!,
last_login_date: String,
reset_password_token: String
}
type Query {
user(_id: String!): User!
users(role_id: Int): [User!]!
}
User Resolver:
Query: {
user: (parent, args) => User.findById(args._id),
users: (parent, args) => {
if (args.role_id) {
return User.find({ role_id: args.role_id })
}
return User.find({})
},
},
Site Schema:
type Site {
site_name: String!,
use_policy: String!,
redirect_url: String!,
intro_text: String!,
logo: String!,
address_line_1: String!,
address_line_2: String,
address_city: String!,
address_county: String!,
address_postcode: String!,
phone: String!,
site_reference: Int!,
site_managers: [User],
business_id: String!,
connect_duration: Int!,
created_date: String!,
updated_date: String!,
}
type Query {
site(site_reference: Int!): Site!
sites(business_id: Int!): [Site!]!
}
Site Resolver:
Query: {
site: (parent, args) =>
Site.findOne({ site_reference: args.site_reference }),
sites: (parent, args) => Site.find({ business_id: args.business_id }),
},
I imagine I need to do more in my resolver for the site query but I am unsure of what exactly. I have already tried using mongoose.populate but to no avail, the furthest I got was returning an empty array with the populate method.
Thanks in advance for your time.
Edit: Here's my mongoose schemas
User Schema
const UserSchema = new mongoose.Schema({
first_name: { type: String, required: true },
last_name: { type: String, required: true },
role_id: { type: Number, required: true },
email: { type: String, required: true },
password: { type: String },
created_date: { type: Date, default: Date.now, required: true },
updated_date: { type: Date, default: Date.now, required: true },
last_login_date: { type: Date },
reset_password_token: { type: String },
})
Site Schema:
const SiteSchema = new mongoose.Schema({
site_name: { type: String, required: true },
use_policy: {
type: String,
required: true,
default: config.defaultUsePolicy,
},
redirect_url: {
type: String,
required: true,
default: config.defaultRedirect,
},
intro_text: {
type: String,
required: true,
default: config.defaultIntroText,
},
logo: { type: String, required: true, default: config.defaultLogo },
address_line_1: { type: String, required: true },
address_line_2: String,
address_city: { type: String, required: true },
address_county: { type: String, required: true },
address_postcode: { type: String, required: true },
phone: { type: String, required: true },
site_reference: { type: String, required: true },
site_managers: {type:[mongoose.Schema.Types.ObjectId], required: true}
business_id: { type: mongoose.Schema.Types.ObjectId, required: true },
connect_duration: { type: Number, required: true, default: 0 },
created_date: { type: Date, default: Date.now, required: true },
updated_date: { type: Date, default: Date.now, required: true },
})
If you're using MongoDB and mongoose, you will want to use populate
to join your collections. In order to do so, in your schema, the field you're populating needs to not only have a type, but also a ref
property that tells mongoose which Model to use to populate the field, for example:
// Note the actual ref should be whatever name you passed to mongoose.model
site_managers: [{type:mongoose.Schema.Types.ObjectId, ref: 'User'}]
Now, use populate
inside your resolver:
site: (parent, { site_reference }) => {
return Site.findOne({ site_reference }).populate('site_managers').exec()
}
See the docs for more detailed examples.