Mutation doesn't work GraphQL, Prisma, Yoga - graphql

How to add User in this example? I try to use mutation in all ways but doesn't work.
type User {
masterId: Int
name: String
surname: String
address: Address
}
type Address {
street: String
flat: Int
city: String
country: String
}
I try something like this:
type Mutation {
user(
masterId: Int
name: String
surname: String
address: Address
): User
}
and next
mutation {
user(
masterId: 4,
name: "Kevin",
surname: "Key",
address: {
street: "Clark Street",
flat: 19,
city: "Brentwood",
country: "United Kingdom"
}
)
}
I try different versions, but I really can not find a solution

Try this in the playground after creating datamodel in prisma
mutation {
createUser(
data: {
name: "Kevin",
surname: "Key"
address: {
create: {
street: "Clark Street",
flat: 19,
city: "Brentwood",
country: "United Kingdom"
}
}
}
) {
id
name
}
}
Note
You also use connect if address object is already created, for connect just pass the Address id(Primary Key/ObjectId)

Related

Graphql React Dev Tools Missing field while writing result

I am running a graphql query to create a person object. The query works fine and the person is created. However I am receiving the following error in the console
react_devtools_backend.js:2842 Missing field 'create_person' while writing result {
"__typename": "PersonResponse",
"error": null,
"person": {
"__typename": "Person",
"hire_date": "2020-10-01",
"name": {
"__typename": "Name",
"first_name": "Joe",
"last_name": "Doe",
"middle_name": ""
},
"person_id": {
"__typename": "PersonId",
"id_": "44df8f7c-d019-410c-89b4-be602f631055"
},
"preferred_name": {
"__typename": "PreferredName",
"first_name": "J",
"last_name": "Dee",
"middle_name": null
}
},
"status": 201
}
This error seems to be saying that my query is missing a field create_person however create_person is not a field it is the name of the query. My first thought was that the message is due to the null fields (even though they are not required). I tried removing these fields from the schema and I still get the error. I am using React Dev Tools chrome extension but still not sure why I get this error.
As requested the gql schema:
const graphqlSchema = buildSchema(`
type Query {
people(person_id: String): [Person]!
emergency_contacts(
person_id: String!
emergency_contact_id: String
): [EmergencyContact]!
person_success: PersonResponse!
person_not_found: PersonResponse!
person_deleted: PersonResponse!
emergency_contact_success: EmergencyContactResponse!
}
scalar Datetime
type PersonId {
id_: String!
}
type Name {
first_name: String!
last_name: String!
middle_name: String
}
input NameInput {
first_name: String!
last_name: String!
middle_name: String
}
input UpdateNameInput {
first_name: String
last_name: String
middle_name: String
}
type ExemptStatus {
code: String!
description: String!
}
type PreferredName {
first_name: String
last_name: String
middle_name: String
}
input PreferredNameInput {
first_name: String
last_name: String
middle_name: String
}
type Relationship {
code: String!
display: String!
description: String!
}
type Address {
line_1: String!
line_2: String!
city: String!
state: String!
zip_code: String!
}
type Person {
person_id: PersonId!
name: Name!
hire_date: Datetime!
preferred_name: PreferredName
contact_info: ContactInfo
exempt_status: ExemptStatus
hired_hours_per_week: Float
hired_hours_per_two_weeks: Float
emergency_contacts: [EmergencyContact]
}
type PersonResponse {
status: Int
error: String
person: Person
}
input PersonInput {
name: NameInput!
hire_date: Datetime!
preferred_name: PreferredNameInput
contact_info: ContactInfoInput
exempt_status_code: String
hired_hours_per_week: Float
hired_hours_per_two_weeks: Float
}
input AddressInput {
line_1: String!
line_2: String!
city: String!
state: String!
zip_code: String!
}
type ContactInfo {
primary_phone: String!
alternate_phone: String
email: String
address: Address
}
input ContactInfoInput {
primary_phone: String!
alternate_phone: String
email: String
address: AddressInput
}
type EmergencyContactId {
id_: String!
}
type EmergencyContact {
emergency_contact_id: EmergencyContactId!
name: Name!
relationship: Relationship!
contact_info: ContactInfo!
}
input EmergencyContactInput {
name: NameInput!
relationship_code: String!
contact_info: ContactInfoInput!
}
input UpdateEmergencyContactInput {
name: NameInput
relationship_code: String
contact_info: ContactInfoInput
}
type EmergencyContactResponse {
status: Int
error: String
person_id: PersonId
emergency_contact: EmergencyContact
}
type Mutation {
create_person(person_input: PersonInput): PersonResponse
update_name(person_id: String!, name_input: UpdateNameInput!): PersonResponse
update_hire_date(person_id: String!, hire_date: Datetime!): PersonResponse
update_preferred_name(
person_id: String!
preferred_name_input: UpdateNameInput!
): PersonResponse
delete_person(person_id: String!): PersonResponse
}
`);

How to pass nested variables to the GraphQL query in Apollo?

Trying to pass nested variables to the GraphQL query but my server gets only top-level variables (shopId), everything else is null.
I tried:
#1
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice(
$shopId: String!
$address1: String
$zip: String
$city: String
$countryCode: String
) {
calculatePackagePrice(
where: {
shopId: $shopId
destination: {
address1: $address1
zip: $zip
city: $city
countryCode: $countryCode
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
)
And #2:
export function CALCULATE_PACKAGE_PRICE({ shopId, destination }) {
return gql`
query CalculatePackagePrice {
calculatePackagePrice(
where: {
shopId: "${shopId}"
destination: {
address1: "${destination.address1}"
zip: "${destination.zip}
city: "${destination.city}"
countryCode: "${destination.countryCode}"
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
}
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE({
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
})
)
It works just fine when I hardcoded variables content to the queries. What I'm doing wrong?
Here is a helpful snippet from graphql docs,
All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server.
You're correctly passing in the variables as strings, but then trying (perhaps successfully, but I've never seen the syntax before) to create the object in the gql template string. Instead, create an input type for destination and where.
input WhereInput {
shopId: String!
destination: DestinationInput!
}
input DestinationInput {
address1: String!
zip: String!
city: String!
countryCode: String!
}
then change the query on the client (and update the server definition),
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice($where: WhereInput!) {
calculatePackagePrice(where: $where) {
name
price
userErrors {
field
message
}
}
}
`
then pass the variables like,
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
where: {
shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
}
)

"Variable '$data' expected value of type 'VoteCreateInput"

When I am trying to do the "vote" mutation, getting the below error. My other mutations are working fine.
When I am trying to do the "vote" mutation, getting the below error. My other mutations are working fine.
When I am trying to do the "vote" mutation, getting the below error. My other mutations are working fine.
"data": null,
"errors": [
{
"message": "Variable '$data' expected value of type 'VoteCreateInput!' but
got: {\"user\":{\"connect\":
{\"id\":\"ck1j3nzi68oef090830r8wd6b\"}},\"link\":{\"connect\":
{\"id\":\"ck1j58loj8x570908njwe4eu7\"}}}. Reason: 'User' Expected non-null
value, found null. (line 1, column 11):\nmutation ($data:
VoteCreateInput!) {\n ^",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"vote"
]
}
]
Mutation
async function vote(parent, args, context, info) {
// 1
const userId = getUserId(context)
// 2
const linkExists = await context.prisma.$exists.vote({
user: { id: userId },
link: { id: args.linkId },
})
if (linkExists) {
throw new Error(`Already voted for link: ${args.linkId}`)
}
// 3
return context.prisma.createVote({
user: { connect: { id: userId } },
link: { connect: { id: args.linkId } },
})
}
datamodel.schema
type Link {
id: ID! #id
createdAt: DateTime! #createdAt
description: String!
url: String!
postedBy: User
votes: [Vote!]!
}
type User {
id: ID! #id
name: String!
email: String #unique
password: String!
links: [Link!]!
votes: [Vote!]!
}
type Vote {
id: ID! #id
link: Link!
user: User!
}
schema.graphql
type Mutation {
vote(linkId: ID!): Vote!
}
type Link {
id: ID!
description: String!
url: String!
postedBy: User
votes: [Vote!]!
}
There was a glitch in prisma database which was not updating with the change in data model.
I have created a new instance of the db and now its working fine.

Prisma graphql computed fields on relations

I have the following datamodel:
type Tvshow {
id: ID! #unique
title: String!
pricing: [Pricing]
startDate: DateTime!
endDate: DateTime!
subscribers: [Tvshowsubscription!]
.....
}
type FavoriteTvshow {
id: ID! #unique
tvshow: Tvshow!
user: User!
}
type User {
id: ID! #unique
name: String
email: String! #unique
password: String
googleID: String #unique
resetToken: String
resetTokenExpiry: String
permissions: [Permission]
address: Address
phone: String
favorites: [FavoriteTvshow!]
tvshowSubscriptions: [Tvshowsubscription!]
}
I have my custom Tvshow resolver using addFragmentToInfo:
resolver-queries.js
const Query = {
...
favoriteTvshows: forwardTo('db'),
tvshow: (parent, args, ctx, info) => {
const fragment = `fragment EnsureComputedFields on Tvshow { pricing { minQuantity maxQuantity unitPrice} subscribers { id }}`
return ctx.db.query.tvshow({}, addFragmentToInfo(info, fragment))
},
....
};
tvshow-resolver.js
const Tvshow = {
countSubscribers: (parent) => {
return parent.subscribers.length;
},
}
This is an example, I have more computed fields for Tvshow
I can query Tvshows with countSubscribers, It works fine doing something like this:
query SINGLE_TVSHOW_QUERY($id: ID!) {
tvshow(where: { id: $id }) {
id
title
pricing {
minQuantity
maxQuantity
unitPrice
}
startDate
endDate
countSubscribers
}
}
But what I want to do is to get all the favorite Tvshows from an user returning the countSubscribers, a query for that could be something like this:
query FAVORITES_FROM_USER($userId: ID!) {
favoriteTvshows(where: { user: {id: $userId} }) {
tvshow {
id
title
startDate
endDate
countSubscribers
}
}
}
The problem is that when I query this, in the tvshow-resolver.js I mentioned before, the parent doesn’t have any subscribers object
The error was very silly but I will post it anyway. I needed subscribers in the query
query FAVORITES_FROM_USER($userId: ID!) {
favoriteTvshows(where: { user: {id: $userId} }) {
tvshow {
id
title
startDate
endDate
subscribers { <---
id
quantity
}
countSubscribers
}
}
}
That way the parent in tvshow-resolver.js will have subscribers object

How to mutate nested object using graphql

I have a mongoose schema like the one below:
import mongoose from 'mongoose'
const ProjectSchema = new mongoose.Schema({
name: {
type: String
},
owner: {
type: String
},
member: {
type: String
},
updatedDate: {
type: Date
},
description: {
type: String
},
folder: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Folder'
},
dataSources: [{
name: {
type: String
},
updatedDate: {
type: Date
},
}],
propjectHistory: [{
no: {
type: Number
},
member: { // is this reference or just a string?
type: String
},
action: {
type: String
},
updatedDate: {
type: Date
},
}]
})
const Project = mongoose.model('Project', ProjectSchema)
And I integrated with graphql using graffiti and graffiti-mongoose.
However, the Graphiql documentation shows that I only have the ones below:
addProject(input: addProjectInput!):
name: String
owner: String
member: String
updatedDate: Date
description: String
folder: ID
clientMutationId: String!
I could successfully add project with a mutation query only using those parameters, but it seems that I cannot even send mutation query with projectHistory and dataSource, which are embedded inside project schema.
However, I can access projectHistory and dataSource when I send find queries.
I can't find any documentation about the problem.
sample mutation query without nested ones works.
mutation {
addProject(input:{
clientMutationId: "1"
name: "testproject",
owner: "keonwoo",
member: "keonwoo",
updatedDate: "2015-07-24T13:23:15.580Z",
description: "this is test project",
folder: "56fb93403eab9e1c14358fb7"
}){
clientMutationId
changedProjectEdge{
node{
_id
name
updatedDate
}
}
}
}
the above mutation returns the following:
{
"data": {
"addProject": {
"clientMutationId": "1",
"changedProjectEdge": {
"node": {
"_id": "56fb93ab3eab9e1c14358fb8",
"name": "testproject",
"updatedDate": "2015-07-24T13:23:15.580Z"
}
}
}
}
}
I am not using client like relay.
the problem was with the graffiti-mongoose library.
Turns out that maintainers of graffiti-mongoose just added embedded object feature and I did not update.

Resources