Partial Update Mutations(GraphQL) - graphql

How can I be able to update a node with only one field change and leave the rest of the fields alone?
My User Type
type User {
id: ID!
user_id: String!
username: String!
email: String!
role: Role!
isVerified: Boolean!
}
My Input Types
input UserUpdateInput {
user_id: String
username: String
email: String
password: String
role: Role
isVerified: Boolean
}
input UserWhereUniqueInput {
id: ID
user_id: String
email: String
}
My Mutation type
type Mutation {
updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput): User
}
My Resolver
function updateUser(root, args, context, info){
return context.db.mutation.updateUser({
data: args.data,
where: {
id: args.where.id
}
}, info)
}
This is the request am sending on the GraphQL playground
mutation{
updateUser(
data: {
isVerified: true
}
where:{
user_id : "afc485b"
}
)
{
isVerified
}
}
This is the error am getting
{
"errors": [
{
"message": "Cannot read property 'mutation' of undefined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"updateUser"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Cannot read property 'mutation' of undefined"
Someone help me. What am I missing?
After updating my server as suggested by Daniel Rearden on the answer section, am getting a new error
{
"message": "Cannot read property 'updateUser' of undefined",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"updateUser"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Cannot read property 'updateUser' of undefined"

The error is the result of not correctly adding the db property to you context. Assuming you're still using version 1, your code should look something like this:
const { prisma } = require('./generated/prisma-client')
const server = new ApolloServer({
...
context: {
db: prisma,
},
})

First thing I notice is you GQL query is not correct.
Yours:
mutation{
updateUser(
data: {
isVerified: true
}
where:{
user_id : "afc485b"
}
)
{
isVerified
}
}
after the word "mutation" you set a name to the call, i.e.
"UpdateUser" but can literally be anything. for each part of the
where clause you need to make the check value an object, i.e.
where: { myProperty: {eq: "some value"}}
So your query should be more like this:
mutation UpdateUser {
updateUser(
data: {isVerified: true}
where:{user_id : {eq: "afc485b"}}
)
{
isVerified
}
}
Hope that helps a little... I didn't fully read the rest but thought this would help with the initial error you were getting.

Related

Cannot read properties of null (reading '_doc')

I'm running a query in GraphQL and getting this error:
{
"errors": [
{
"message": "Cannot read properties of null (reading '_doc')",
"locations": [
{
"line": 38,
"column": 5
}
],
"path": [
"songs",
0,
"creator"
]
}
],
"data": null
}
This is the query.
query {
songs {
song_file_name
song_type
song_size
user_name
creator {
email
}
This is my resolver file, and this is the schema.
const { buildSchema } = require('graphql');
module.exports = buildSchema(`
type Song {
_id: ID!
song_file_name: String!
song_type: String!
song_size: Int!
user_name: String!
creator: User!
}
type User {
_id: ID!
email: String!
password: String
createdSongs: [Song!]
}
input SongInput {
song_file_name: String!
song_type: String!
song_size: Int!
user_name: String!
}
input UserInput {
email: String!
password: String!
}
type RootQuery {
songs: [Song!]!
}
type RootMutation {
createSong(songInput: SongInput): Song
createUser(userInput: UserInput): User
}
schema {
query: RootQuery
mutation: RootMutation
}
`);
Could anyone help me figure out what I'm doing wrong? It looks like creator is returning null, but it is properly defined as far as I can tell. What's causing this?
Also, can anyone suggest a good place to learn GraphQL? I'm following this guide and though I find it useful and informative, it quickly gets to a level where I don't feel I fully understand what I'm doing although I'm following along.
I know the basics of GraphQL, but the relational concepts is hard for me to wrap my head around.

How to handle graphql errors on Apollo server? [duplicate]

In an express-graphql app, I have a userLogin resolver like so:
const userLogin = async ({ id, password }), context, info) => {
if (!id) {
throw new Error('No id provided.')
}
if (!password) {
throw new Error('No password provided.')
}
// actual resolver logic here
// …
}
If the user doesn't provide an id AND a password, it will throw only one error.
{
"errors": [
{
"message": "No id provided.",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"userLogin"
]
}
],
"data": {
"userLogin": null
}
}
How is it possible to throw multiple errors in the errors response array?
There is no way to throw an array of errors in JavaScript or otherwise have a single resolver reject with more than one error. A GraphQL response includes an errors array and not just a single error object because the total response can include multiple errors when those errors originate from different fields. Consider this schema and resolvers:
type Query {
a: String
b: String
c: String
}
const resolvers = {
Query: {
a: () => { throw new Error('A rejected') },
b: () => { throw new Error('B rejected') },
c: () => 'Still works!',
},
}
If you query all three fields...
query {
a
b
c
}
Your data will look something like this:
{
"errors": [
{
"message": "A rejected",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"a"
]
},
{
"message": "B rejected",
"locations": [
{
"line": 3,
"column": 3
}
],
"path": [
"b"
]
}
],
"data": {
"a": null,
"b": null,
"c": "Still works!"
}
}
This is because GraphQL supports partial responses. However, keep in mind that this works because the fields are nullable. If they were non-null, those errors would bubble up to the closest nullable parent field.
Here are some alternative approaches:
You can utilize formatError to change how the errors returned by GraphQL are displayed to the client. That means you can include any sort of extra information with your errors, like an error code or multiple error messages. A simple example:
// The middleware
app.use('/graphql', graphqlExpress({
schema: schema,
formatError: (error) => ({
message: error.message,
path: error.path,
locations: error.locations,
errors: error.originalError.details
})
}))
// The error class
class CustomError extends Error {
constructor(detailsArray) {
this.message = String(details)
this.details = details
}
}
// The resolver
const userLogin = async ({ id, password }), context, info) => {
const errorDetails = []
if (!id) errorDetails.push('No id provided.')
if (!password) errorDetails.push('No password provided.')
if (errorDetails.length) throw new CustomError(errorDetails)
// actual resolver logic here
}
Your response then looks more like this:
{
"errors": [
{
"message": "[No id provided.,No password provided.]",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"userLogin"
]
"errors" [
"No id provided.",
"No password provided."
]
}
],
"data": {
"userLogin": null
}
}
That said, there's something a bit unsavory about returning user-facing error messages alongside GraphQL validation errors. Another approach that some APIs have taken is to include an errors field alongside the actual mutation response. For example:
type Mutation {
userLogin: UserLoginResponse
}
type UserLoginResponse {
response: User
errors: [String!]
}
You can also use unions to achieve a similar effect:
type Mutation {
userLogin: UserLoginResponse
}
type Errors {
errors: [String!]!
}
union UserLoginResponse = User | Errors

Cannot Return null or non-nullable field User.Role not able to retrive relation data from prisma mutation

I am trying play arroud APOLO SERVER, GRAPHQL PRISMA and struct at very basic thing .. I am not able to return relation data from simple query ..
WHen i try to add user along with role id .. i am not able to get role information back
WHat i am using ?
"dependencies": {
"apollo-server": "^2.9.3",
"bcryptjs": "^2.4.3",
"graphql": "^14.5.5",
"graphql-import": "^0.7.1",
"jsonwebtoken": "^8.5.1",
"prisma-client-lib": "^1.34.8"
}
for My SIMPLE QUERY ;
mutation{
createUser(name:"tst",
roleId:"ck0lx425n00z50782jgcl4qg8")
{
name
role{
code}
Graphql returning error saying
{
"errors": [
{
"message": "Cannot return null for non-nullable field User.role.",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"createUser",
"role"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field User.role.",
GAPHQL SHCHEMA
scalar DateTime
type User {
id: ID!
name: String!
role:Role!
createdAt:DateTime
}
type Role{
id:ID!,
code:String!
users:[User!]!
}
type Query {
users:[User!]!
user:User!
roles:[Role!]!
role:Role!
}
type Mutation {
createRole(code:String!):Role!
createUser(name:String!,roleId:String!):User!
}
QUERY
function users(parent, args, context) {
return context.prisma.uses()
}
function roles(parent,args,context){
return context.prisma.roles()
}
MUTAIONS
function createRole(parent,args,context,info){
return context.prisma.createRole({
code:args.code
});
function createUser(parent,args,context,info){
return context.prisma.createUser({
name:args.name,
role:{
connect:{id:args.roleId}
}
},info);
}
PRISMA DATAMODEL
type User {
id: ID! #id
name:String!
createdAt:DateTime #createdAt
role:Role! #relation(Name:"Role Assinged To User")
}
type Role{
id:ID! #id
code:String!
users:[User!]! #relation(Name:"Role Assinged To User")
}
can some body help me , how to fix is this .. I know it will be basic one that i missing out .. I am struggling to understand ? am i missing something very basic ?
When you create roles you would need to also specify a user since you made it a requirement that can cause errors

GraphQL mutation issue

I am new in GraphQL. I am learning GraphQL.
My input is like below
mutation {
createEvent:{eventInput: {title: "A Test", description:"Does this work?", price:9.99, date:"2018-12-06T09:26:30.645Z"}
}
}
I am getting error like below
{
"errors": [
{
"message": "Syntax Error: Expected Name, found {",
"locations": [
{
"line": 2,
"column": 15
}
]
}
]
}
Well, I believe your createEvent mutation should return an object type. And for the object type , you have to specify at least one of the field from of return type for this Mutation.
It should be :
mutation {
createEvent(eventInput: {
title: "A Test"
description:"Does this work?"
price:9.99
date:"2018-12-06T09:26:30.645Z"
}){
someFieldInTheReturnType
}
}

Trying to delete using Mutation but its giving the error saying authorsCollection.delete is not a function

When I try to run it, It is giving me the error.Trying to delete using Mutation but its giving the error saying "authorsCollection.delete" is not a function
const Mutation = new GraphQLObjectType({
name: "Mutations",
fields: {
DeleteAuthor: {
type: Author,
args: {
_id: {type: new GraphQLNonNull(GraphQLString)},
name: {type: GraphQLString},
},
resolve: function(rootValue, args) {
let author = Object.assign({}, args);
console.log(args);
return authorsCollection.delete(author._id)
.then(_ => author);
}
}
What should be edited in the code so that I can implemented the Delete operation?
It is giving me the error as below
{
"data": {
"DeleteAuthor": null
},
"errors": [
{
"message": "authorsCollection.delete is not a function",
"locations": [
{
"line": 2,
"column": 3
}
]
}
]
}
The error message authorsCollection.delete is not a function indicates that authorsCollection does not have any function named delete. In your jsfiddle code, I see you have used promised-mongo library. The API to remove documents is remove, not delete.
Change to
authorsCollection.remove({_id: ObjectId(author._id)})
The _id passed is a string. But the _id property of author in DB is of type ObjectID. So, you have to convert it to ObjectID type. You do so by using promised-mongo's ObjectId. So, import it in the beginning:
import {ObjectId} from 'promised-mongo';

Resources