i have come across an oddity in what gets returned when i run similar mutations. i am just learning this stack, and i implement mongodb with mongoose as my database layer.
i have two simple mutations. one creates a user and adds it to the database aka register. the other adds a profile pic obviously after the initial user object is created.
both resolvers return the full user object, which is nice to do for updating the ui, store, etc, i am planning on implementing subscriptions so it is important that i get the new data back.
i was working thing out with graphiql and ran into a weird problem. my update resolver was returning null even though the image url was getting saved to the db. the register resolver was returning all the user fields.
upon console logging the return objects in the resolvers, both functions were returning a full user object.
when i tried to make the return object non nullable i would get the error cant return null for non nullable for the update resolver.
my resolver was initially using findOneAndUpdate with a callback that did in fact return the user object. and yes, i was still getting null. weird.
i changed my resolver to instead a more manual approach. i look up the existing user with findOne passing in the user id, then explicitly saying user.profilePic = "url of pic" and the calling save of the whole user object and returning the user object in the callback to that. and boom, that works!
so what is causing this? i get the initial feeling that this has something to do with timing somehow aka the not waiting for the callback....i really dont understand why my first approach doesn't work and my second does. i will attach the code for both maybe someone with a deeper understanding of timing or possibly async functions can chime in. maybe i need to update my style from callbacks to promises or async await.
//this one doesnt work
addProfilePic: (root, { input }, context) => {
let update = { profilePic: input.profilePic };
let query = { id: input.id };
let options = { new: true, upsert: true};
let callback = ((err, user) => {
if(err) console.log(err.message);
return user;
})
return updatedUser = User.findOneAndUpdate(query, update, options, callback)
}
//this one works, but returns old user object to client...
//so really, no, it doesn't work
addProfilePic: (root, { input }, context) => {
return User.findOne({id: input.id}, ((err,user) => {
if(err)console.log(err);
if(user){
user.profilePic = input.profilePic;
user.save((err) => {
if(err)console.log(err);
console.log(user);
return user;
})
}
})
})
note: passing in context, when i actually implement i will get id from context, which contains the user when they are logged in. note: these are soon cool tools, but a lot to learn, especially for someone with 3 months total coding exp...ie me...