I added another field(contacts) to my apollo graphql mutation but when retrieving the field it produces false data. Even if the matching mongodb field has real data or not, graphql returns mutliple fields with null values.
I've already tried removing __typename in the apollo client graphql options but it doesn't help. Current stack is:
reactjs 16.8.5
react-apollo 2.5.2
mongodb 3.6.11
mongoose 5.3.6
apollo-server 2.3.1
I don't understand why it does this since I have another subdocument that is almost identical but returns correctly.
// CLIENTSIDE
// APOLLO SETUP
const cache = new InMemoryCache({
dataIdFromObject: object => object.key || null
})
const AuthLink = (operation, forward) => {
const token = cookies._uid
operation.setContext(context => ({
...context,
headers: {
...context.headers,
authorization: token
}
}))
return forward(operation)
}
const httpLink = new HttpLink({
uri:"/graphql",
credentials: "include"
})
// mutation
export const LOGIN_MUTATION = gql`
mutation loginMutation($email: String!, $password: String!) {
login(input: {email: $email, password: $password}) {
token
user {
_id
contacts { // This is the subfield in question
_id
username
}
subscriptions { // This subfield returns corretly
_id
title
levels {
_id
}
}
}
error {
path
message
}
}
}
`
// SERVERSIDE
// APOLLO SETUP
const baseSchema = `
schema {
query: Query,
mutation: Mutation
}
`
const schema = makeExecutableSchema({
typeDefs: [
userTypeDefs,
],
resolvers: merge(
{},
userResolvers,
)
})
const {ObjectId} = mongoose.Types
ObjectId.prototype.valueOf = function() {
return this.toString()
}
export default new ApolloServer({
introspection: true,
credentials: true,
schema,
context: ({req, res}) => ({
url: req.protocol + "://" + req.get("host"),
req
})
})
// USER MONGOOSE MODEL
export const UserSchema = new mongoose.Schema(
{
contacts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
],
firstName: {
type: String
},
lastName: {
type: String
},
username: {
type: String,
lowercase: true,
unique: true,
required: [true, "can't be blank"],
match: [/^[a-zA-Z0-9]+$/, "is invalid"],
index: true
},
sentRequests: [
{
username: {
type: String,
default: ""
}
}
],
subscriptions: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Course"
}
],
password: {
default: "",
required: [true, "can't be blank"],
type: String
}
},
{timestamps: true}
)
UserSchema.plugin(uniqueValidator, {message: "is already taken."})
export default mongoose.model("User", UserSchema)
// USER GRAPHQL SCHEMA
type User {
_id: ID
contacts: [User]
email: String!
username: String
subscriptions: [Course]
createdAt: String
updatedAt: String
}
type AuthPayload {
token: String
user: User
error: [Error]
}
input LoginInput {
email: String!
password: String!
}
type Mutation {
login(input: LoginInput): AuthPayload
}
// USER RESOLVER
const login = async (parent, args, ctx, info) => {
let email = args.email
let user = await User.findOne({email})
.populate("subscriptions")
.populate("contacts")
.exec()
if (!user) {
arrayOfErrors.push({
path: "email",
message: "invalid email"
})
} else if (user) {
console.log("user: ", user)
return {
user,
error: arrayOfErrors
}
}
Mutation: {
login
}
// CONSOLE LOG CLIENTSIDE
user:
confirmed: true
contacts: Array(3) // returns an array of 3 items?? It's [] in mongodb
0: {_id: null, username: null}
1: {_id: null, username: null}
2: {_id: null, username: null}
length: 3
__proto__: Array(0)
subscriptions: Array(1)
0: {_id: "5cd36fc1c8d1e222b99d9c58", title: "Korean Class 101 Study",
length: 1
__proto__: Object
__proto__: Object
// CONSOLE LOG SERVERSIDE
POST /graphql 200 64.359 ms - -
user: {
contacts: [ ],
subscriptions:
[ { _id: 5cd6f7f8212af32c75555d4b,
subscribers: 2,
owner: 5cd36edec8d1e222b99d9c57,
createdAt: 2019-05-09T00:09:37.845Z,
updatedAt: 2019-05-11T16:36:14.661Z,
__v: 23 } ],
password: '$2b$10$bkjiazklcoqlkJSJSAioxoAqkoajsdjnqjkiaallaadfadfp7zS',
_id: 5cd36edec8d1e222b99d9c57,
email: '[email protected]',
username: 'example',
createdAt: 2019-05-09T00:05:50.314Z,
updatedAt: 2019-05-29T17:23:21.545Z,
__v: 32
}
I expected an empty array to return [ ], instead graphql returns an array of 3 items with null values. Even if I add real contacts into the database it still returns the 3 items with null values. The subscriptions are returning correctly yet it is almost identical to the contacts field with the exception of being a type "Course" in the mongoose model instead of type "User".