Mutation with list of strings as argument in Prisma + GraphQL - list

I am trying to make a mutation but I am getting an error with the arguments.
In schema.graphql I have the following:
type User {
id: ID!
name: String!
email: String!
age: Int!
height: Float!
weight: Float!
goals: [String!]!
history: [Routine!]!
}
type Mutation {
signup(email: String!, password: String!, name: String!, age: Int!, height: Float!, weight: Float!, goals: [String!]!): AuthPayload
}
In schema.prisma:
model User {
id Int #id #default(autoincrement())
name String
email String #unique
password String
age Int
weight Float
height Float
goals String[]
history Routine[]
}
Then my mutation resolver is the following:
async function signup(parent, args, context, info) {
// 1
const password = await bcrypt.hash(args.password, 10)
// 2
const user = await context.prisma.user.create({ data: { ...args, password } })
// 3
const token = jwt.sign({ userId: user.id }, APP_SECRET)
// 4
return {
token,
user,
}
}
But when I try the function on GraphQL Playground for example with:
mutation {
signup(
name: "Esteban"
email: "esteban#gmail.com"
password: "Password"
age: 23
height: 1.84
weight: 70.0
goals: ["WEIGHT_LOSS"]
) {
token
user {
id
}
}
}
I get the following error:
{
"data": {
"signup": null
},
"errors": [
{
"message": "\nInvalid `context.prisma.user.create()` invocation in\n/Users/estebankramer1/Documents/ITBA/pf-proyf/server/src/resolvers/Mutation.js:10:42\n\n 6 // 1\n 7 const password = await bcrypt.hash(args.password, 10)\n 8 \n 9 // 2\n→ 10 const user = await context.prisma.user.create({\n data: {\n email: 'esteban#gmail.com',\n password: '$2a$10$hL1sMErBEcg98hpk5kRNpef2isI5d/O66zfRom8sQyThIHue7ku2O',\n name: 'Esteban',\n age: 23,\n height: 1.84,\n weight: 70,\n goals: [\n 'WEIGHT_LOSS'\n ]\n }\n })\n\nUnknown arg `0` in data.goals.0 for type UserCreategoalsInput. Available args:\n\ntype UserCreategoalsInput {\n set?: List<String>\n}\n\n",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"signup"
]
}
]
}
I don't know what I am doing wrong and I cannot find examples of Mutations with lists of strings.

It turns out I needed to change the mutation to the following:
async function signup(parent, args, context, info) {
// 1
const password = await bcrypt.hash(args.password, 10)
// 2
const user = await context.prisma.user.create({ data: {
...args,
goals: {
set: args.goals
},
password
} })
// 3
const token = jwt.sign({ userId: user.id }, APP_SECRET)
// 4
return {
token,
user,
}
}
Basically use a set operation.
I have no idea why, the documentation of Prisma is terrible. Maybe someone can clear things a bit?

Related

How do you test express controllers that use mongoose models?

In my controller i have a function that creates a user but also checks to make sure that the user does not already exist and then a dashboard function which gets the user from the request and returns any petitions that have been created by that user.
I've looked at mocha, chai and sinon to carry out the tests along with various online resources but have no idea how to begin testing these two functions since they rely on models. Can anyone point me in the right direction to testing the controller or know of any resources which maybe able to help me?
Controller:
const bcrypt = require('bcryptjs');
const passport = require('passport');
const Users = require('../models/Users');
const Petitions = require('../models/Petitions');
const UserController = {
async register(req, res) {
const {name, email, password, passwordCon} = req.body;
let errors = []
// check required fields
if (!name || !email || !password || !passwordCon) {
errors.push({ msg: 'Please enter all fields' });
}
// check passwords match
if (password !== passwordCon) {
errors.push({ msg: 'Passwords do not match' });
}
// check password length
if (password.length < 6) {
errors.push({ msg: 'Password must be at least 6 characters' });
}
// if validation fails, render messages
if (errors.length > 0) {
res.render('user/register', {
errors,
name,
email,
password,
passwordCon
})
} else {
// validation passed
Users.findOne({email: email})
.then(user => {
if (user) {
// user exists
errors.push({msg: 'Email already in use'});
res.render('user/register', {
errors,
name,
email,
password,
passwordCon
});
} else {
const newUser = new Users({
name: name,
email: email,
password: password
});
// hash password
bcrypt.genSalt(10, (error, salt) =>
bcrypt.hash(newUser.password, salt, (error, hash) => {
if (error) throw error;
// set password to hashed
newUser.password = hash;
// save user
newUser.save()
.then(user => {
req.flash('success_msg', 'Registration Success');
res.redirect('/user/login');
})
.catch(error => console.log(error));
}))
}
});
}
},
async dashboard(req, res) {
const user = req.user;
const petitions = await Petitions.find({createdBy: user._id});
console.log('here');
res.render('user/dashboard', {
user: req.user,
petitions: petitions
})
}
};
module.exports = UserController;
Models:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
createdOn: {
type: Date,
default: Date.now
},
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
petitions: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'Petitions' }
]
})
const Users = mongoose.model('Users', UserSchema);
module.exports = Users;
const mongoose = require('mongoose');
const PetitionSchema = new mongoose.Schema({
createdOn: {
type: Date,
default: Date.now
},
title: {
type: String,
required: true
},
signaturesNeeded: {
type: String,
required: true
},
description: {
type: String,
required: true
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
signatures: [
{ type: mongoose.Schema.Types.ObjectId, ref: 'Users' }
]
})
const Petitions = mongoose.model('Petitions', PetitionSchema);
module.exports = Petitions;

One to Many Relationship not showing in the object Amplify Schema definition

I am new to using amplify with GraphQL. I was setting up my DB schema and auto-generating the functions after running amplify push.
Goals I want to achieve but do not know how to are
I would like to be able to get user with all connected information (with one to one and one to many relationships) in the returned object from getUser
I would like to still be able to get userByUserName and see all connected one-to-many relationships as well
When calling the API generated function to get the user,
let user = await API.graphql(graphqlOperation(getUser,{id:userId}))
I am getting a user object back, however, it looks like this - even though I am definitely sure that data is set up correctly in the database.
buttons: {nextToken: null} -- WANT THIS TO INCLUDE ACTUAL INFORMATION ABOUT BUTTONS CONNECTED TO THIS USER
createdAt: "2020-09-02T23:41:12.278Z"
customStyles: {id: "e3d1bbef-ec6f-4a6d-9b5d-e693e890d4e0", bgColor: "F9FF9F", bgBtnColor: "FFFFFF", bgBtnHoverColor: "000000", textColor: "000000", …}
defaultStyles: null
email: "nata#email.edu"
firstName: "Nata"
id: "d683a6bb-383e-4cf1-943a-05b3da4e5cc3"
lastName: "Vache"
socialNetwork: {nextToken: null} -- WANT THIS TO INCLUDE ACTUAL INFORMATION ABOUT SOCIAL NETWORKS CONNECTED TO THIS USER, THE SAME WAY AS FOR EXAMPLE customStyles IS SHOWN.
updatedAt: "2020-09-02T23:41:12.278Z"
userName: "Nata568"
type User #model #key(name: "byUserName", fields: ["userName"], queryField: "userByUserName"){
id: ID!
firstName: String!
lastName: String!
userName: String!
email: String!
socialNetwork: [UserSocialNetwork] #connection(keyName: "UserSocialNetworkUser", fields: ["id"])
buttons: [Button] #connection(keyName: "ButtonUser", fields: ["id"])
defaultStyles: DefaultStyle #connection
customStyles: CustomStyle #connection
}
type UserSocialNetwork #model #key(name: "UserSocialNetworkUser", fields: ["userID", "id"], queryField:"userSocialNetworkByUserID") {
id: ID!
socialNetworkUsername: String!
userID: ID!
supportedSocialNetwork: SupportedSocialNetwork! #connection
}
type SupportedSocialNetwork #model {
id: ID!
name: String!
address: String!
}
type Button #model #key(name: "ButtonUser", fields: ["userID", "id"], queryField: "buttonByUserID") {
id: ID!
name: String!
address: String!
image: String
userID: ID!
}
This schema does not include all my model definitions - customStyles, defaultStyles, and the rest but they are one to one relationship, which is working perfectly fine. I am having issues with one-to-many relationships, such as User to UserSocialNetwork and User to Buttons.
I have read lots of resources about this on AWS Amplify Docs, have gone through examples but still have not found anything that I could work with that would allow me to get the information from connections on getUser call and also give me the ability to get the user by username.
Any input would be appreciated!!!
This is a problem with query Depth. It is 2 by default and need to increase it (to 4 in your case).
You can resolve this by following below steps.
In your cmd in your project root, (where you normally run amplify commands).
Run amplify codegen configure - This will prompt configs again.
Enter 4 for this option Enter maximum statement depth [increase from default if your schema is deeply nested]
Run amplify codegen - this will create your queries and mutations according to the new depth.
You can verify it by checking grapgql/queries.js.
Earlier you could see below fragment in getUser query in grapgql/queries.js,
buttons {
nextToken
}
But after following above resolution steps, it should be something like below.
buttons {
items {
id
image
address
}
}
Finally query for your user again.
General comment: If username is unique you could use that as the id instead of creating the extra index. If it isn't there will be problems with this schema since it can't do a getOperation but instead will do a query which might return multiple answers.
(The resolver in Appsync wants to use a dynamoDB.get by default (& design) but using an index would be a dynamoDB.query which results in a lot issues)
Anyway using your schema I can get it to work just fine when using the id
"data": {
"getUser": {
"createdAt": "2020-09-07T13:54:23.440Z",
"email": "meax",
"firstName": "Max",
"id": "19a752ec-5050-4e02-8ff8-05d9523e7ea5",
"socialNetwork": {
"items": [
{
"socialNetworkUsername": "What",
"id": "280ec8ea-5b25-46d3-8f22-f170e3210146",
"userID": "19a752ec-5050-4e02-8ff8-05d9523e7ea5"
}
]
},
"lastName": "Sc",
"userName": "zanndo",
"updatedAt": "2020-09-07T13:54:23.440Z",
"buttons": {
"items": [
{
"id": "65971568-b388-40a3-b99e-1bff0a730161",
"image": null,
"address": "ButonAdre"
}
]
}
}
}
}
This being my query
getUser(id: "19a752ec-5050-4e02-8ff8-05d9523e7ea5") {
createdAt
email
firstName
id
socialNetwork {
items {
socialNetworkUsername
id
userID
}
}
lastName
userName
updatedAt
buttons {
items {
id
image
address
}
}
}
}
Here is one where I made email the id.
query MyQuery {
getUser(id: "sw#gmail.com") {
id
firstName
lastName
socialNetwork {
items {
socialNetworkUsername
supportedSocialNetwork {
name
id
address
}
}
}
buttons {
items {
id
address
name
}
}
}
}
Also works
{
"data": {
"getUser": {
"id": "sw#gmail.com",
"firstName": "S",
"lastName": "W",
"socialNetwork": {
"items": [
{
"socialNetworkUsername": "SomeUserNameOrSomething",
"supportedSocialNetwork": {
"name": "Supported1",
"id": "daf52246-4b25-402c-9fdd-46f8f35e1b89",
"address": "SupportedAddr"
}
}
]
},
"buttons": {
"items": [
{
"id": "9883bd91-a2f1-479d-ab65-7a4bbe7b2dc4",
"address": "ButtonAddr",
"name": "Button1"
}
]
}
}
}
}
Bonus using your index
userByUserName(userName: "SW") {
items {
buttons {
items {
name
id
}
}
socialNetwork {
items {
socialNetworkUsername
supportedSocialNetwork {
name
}
}
}
}
}
"userByUserName": {
"items": [
{
"buttons": {
"items": [
{
"name": "Button1",
"id": "9883bd91-a2f1-479d-ab65-7a4bbe7b2dc4"
}
]
},
"socialNetwork": {
"items": [
{
"socialNetworkUsername": "SomeUserNameOrSomething",
"supportedSocialNetwork": {
"name": "Supported1"
}
}
]
}
}
]
}
This was the schema I used
type User #model #key(name: "byUserName", fields: ["userName"], queryField: "userByUserName"){
firstName: String!
lastName: String!
userName: String!
id: String!
socialNetwork: [UserSocialNetwork] #connection(keyName: "UserSocialNetworkUser", fields: ["id"])
buttons: [Button] #connection(keyName: "ButtonUser", fields: ["id"])
}
type UserSocialNetwork #model #key(name: "UserSocialNetworkUser", fields: ["userID", "id"], queryField:"userSocialNetworkByUserID") {
id: ID!
socialNetworkUsername: String!
userID: String!
supportedSocialNetwork: SupportedSocialNetwork! #connection
}
type SupportedSocialNetwork #model {
id: ID!
name: String!
address: String!
}
type Button #model #key(name: "ButtonUser", fields: ["userID", "id"], queryField: "buttonByUserID") {
id: ID!
name: String!
address: String!
image: String
userID: String!
}
Maybe I have misunderstood something?

How to work with relationships in aws-appsync?

I am new to aws and graphql. I am working on appsync and trying to create relationships between two types. Following is my schema:
type BadCustomer {
id: ID!
name: String!
phone: AWSPhone
email: AWSEmail
streetAddress: String
dob: AWSDate
passportNumber: String
driversLicenceNumber: String
ipAddress: AWSIPAddress
}
type BadCustomerConnection {
items: [BadCustomer]
nextToken: String
}
input CreateBadCustomerInput {
name: String!
phone: AWSPhone
email: AWSEmail
streetAddress: String
dob: AWSDate
passportNumber: String
driversLicenceNumber: String
ipAddress: AWSIPAddress
}
input CreateDamageInput {
damage: Float!
comment: String
}
input CreateIndustryInput {
name: String!
}
input CreateSubscriberInput {
name: String!
email: AWSEmail!
phone: AWSPhone
streetAddress: String!
subscriberIndustryId: ID!
}
type Damage {
id: ID!
customer: BadCustomer!
industry: Industry!
victim: Subscriber!
damage: Float!
comment: String
}
type DamageConnection {
items: [Damage]
nextToken: String
}
input DeleteBadCustomerInput {
id: ID!
}
input DeleteDamageInput {
id: ID!
}
input DeleteIndustryInput {
id: ID!
}
input DeleteSubscriberInput {
id: ID!
}
type Industry {
id: ID!
name: String!
subscribers(
filter: TableSubscriberFilterInput,
sortDirection: ModelSortDirection,
limit: Int,
nextToken: String
): SubscriberConnection
}
type IndustryConnection {
items: [Industry]
nextToken: String
}
enum ModelSortDirection {
ASC
DESC
}
type Mutation {
createIndustry(input: CreateIndustryInput!): Industry
updateIndustry(input: UpdateIndustryInput!): Industry
deleteIndustry(input: DeleteIndustryInput!): Industry
createSubscriber(input: CreateSubscriberInput!): Subscriber
updateSubscriber(input: UpdateSubscriberInput!): Subscriber
deleteSubscriber(input: DeleteSubscriberInput!): Subscriber
createBadCustomer(input: CreateBadCustomerInput!): BadCustomer
updateBadCustomer(input: UpdateBadCustomerInput!): BadCustomer
deleteBadCustomer(input: DeleteBadCustomerInput!): BadCustomer
createDamage(input: CreateDamageInput!): Damage
updateDamage(input: UpdateDamageInput!): Damage
deleteDamage(input: DeleteDamageInput!): Damage
}
type Query {
getIndustry(id: ID!): Industry
listIndustries(filter: TableIndustryFilterInput, limit: Int, nextToken: String): IndustryConnection
getSubscriber(id: ID!): Subscriber
listSubscribers(filter: TableSubscriberFilterInput, limit: Int, nextToken: String): SubscriberConnection
getBadCustomer(id: ID!): BadCustomer
listBadCustomers(filter: TableBadCustomerFilterInput, limit: Int, nextToken: String): BadCustomerConnection
getDamage(id: ID!): Damage
listDamages(filter: TableDamageFilterInput, limit: Int, nextToken: String): DamageConnection
}
type Subscriber {
id: ID!
name: String!
email: AWSEmail!
phone: AWSPhone
streetAddress: String!
industry: Industry!
}
type SubscriberConnection {
items: [Subscriber]
nextToken: String
}
type Subscription {
onCreateIndustry(id: ID, name: String): Industry
#aws_subscribe(mutations: ["createIndustry"])
onUpdateIndustry(id: ID, name: String): Industry
#aws_subscribe(mutations: ["updateIndustry"])
onDeleteIndustry(id: ID, name: String): Industry
#aws_subscribe(mutations: ["deleteIndustry"])
onCreateSubscriber(
id: ID,
name: String,
email: AWSEmail,
phone: AWSPhone,
streetAddress: String
): Subscriber
#aws_subscribe(mutations: ["createSubscriber"])
onUpdateSubscriber(
id: ID,
name: String,
email: AWSEmail,
phone: AWSPhone,
streetAddress: String
): Subscriber
#aws_subscribe(mutations: ["updateSubscriber"])
onDeleteSubscriber(
id: ID,
name: String,
email: AWSEmail,
phone: AWSPhone,
streetAddress: String
): Subscriber
#aws_subscribe(mutations: ["deleteSubscriber"])
onCreateBadCustomer(
id: ID,
name: String,
phone: AWSPhone,
email: AWSEmail,
streetAddress: String
): BadCustomer
#aws_subscribe(mutations: ["createBadCustomer"])
onUpdateBadCustomer(
id: ID,
name: String,
phone: AWSPhone,
email: AWSEmail,
streetAddress: String
): BadCustomer
#aws_subscribe(mutations: ["updateBadCustomer"])
onDeleteBadCustomer(
id: ID,
name: String,
phone: AWSPhone,
email: AWSEmail,
streetAddress: String
): BadCustomer
#aws_subscribe(mutations: ["deleteBadCustomer"])
onCreateDamage(id: ID, damage: Float, comment: String): Damage
#aws_subscribe(mutations: ["createDamage"])
onUpdateDamage(id: ID, damage: Float, comment: String): Damage
#aws_subscribe(mutations: ["updateDamage"])
onDeleteDamage(id: ID, damage: Float, comment: String): Damage
#aws_subscribe(mutations: ["deleteDamage"])
}
input TableBadCustomerFilterInput {
id: TableIDFilterInput
name: TableStringFilterInput
phone: TableStringFilterInput
email: TableStringFilterInput
streetAddress: TableStringFilterInput
dob: TableStringFilterInput
passportNumber: TableStringFilterInput
driversLicenceNumber: TableStringFilterInput
ipAddress: TableStringFilterInput
}
input TableBooleanFilterInput {
ne: Boolean
eq: Boolean
}
input TableDamageFilterInput {
id: TableIDFilterInput
damage: TableFloatFilterInput
comment: TableStringFilterInput
}
input TableEventFilterInput {
id: TableIDFilterInput
name: TableStringFilterInput
where: TableStringFilterInput
when: TableStringFilterInput
description: TableStringFilterInput
}
input TableFloatFilterInput {
ne: Float
eq: Float
le: Float
lt: Float
ge: Float
gt: Float
contains: Float
notContains: Float
between: [Float]
}
input TableIDFilterInput {
ne: ID
eq: ID
le: ID
lt: ID
ge: ID
gt: ID
contains: ID
notContains: ID
between: [ID]
beginsWith: ID
}
input TableIndustryFilterInput {
id: TableIDFilterInput
name: TableStringFilterInput
}
input TableIntFilterInput {
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
contains: Int
notContains: Int
between: [Int]
}
input TableStringFilterInput {
ne: String
eq: String
le: String
lt: String
ge: String
gt: String
contains: String
notContains: String
between: [String]
beginsWith: String
}
input TableSubscriberFilterInput {
id: TableIDFilterInput
name: TableStringFilterInput
email: TableStringFilterInput
phone: TableStringFilterInput
streetAddress: TableStringFilterInput
}
input UpdateBadCustomerInput {
id: ID!
name: String
phone: AWSPhone
email: AWSEmail
streetAddress: String
dob: AWSDate
passportNumber: String
driversLicenceNumber: String
ipAddress: AWSIPAddress
}
input UpdateDamageInput {
id: ID!
damage: Float
comment: String
}
input UpdateIndustryInput {
id: ID!
name: String
}
input UpdateSubscriberInput {
id: ID!
name: String
email: AWSEmail
phone: AWSPhone
streetAddress: String
subscriberIndustryId: ID
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
I want to setup a relationship between Subscribers and Industry. Each subscriber belongs to one industry. I have setup resolvers for Subscriber.industry and Industry.subscribers.
Subscriber.industry Resolver, Datasource Industry table:
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($util.defaultIfNullOrBlank($ctx.source.subscriberIndustryId, "___xamznone____"))
}
}
Industry.subscribers Resolver, Datasource Subscriber table:
#set( $limit = $util.defaultIfNull($context.args.limit, 10) )
{
"version": "2017-02-28",
"operation": "Query",
"query": {
"expression": "#connectionAttribute = :connectionAttribute",
"expressionNames": {
"#connectionAttribute": "id"
},
"expressionValues": {
":connectionAttribute": {
"S": "$context.source.id"
}
}
},
"scanIndexForward": #if( $context.args.sortDirection )
#if( $context.args.sortDirection == "ASC" )
true
#else
false
#end
#else
true
#end,
"filter": #if( $context.args.filter )
$util.transform.toDynamoDBFilterExpression($ctx.args.filter)
#else
null
#end,
"limit": $limit,
"nextToken": #if( $context.args.nextToken )
"$context.args.nextToken"
#else
null
#end
}
I have following queries:
query ListIndustries {
listIndustries {
items {
id
name
subscribers {
items {
id
name
streetAddress
}
}
}
}
}
query ListSubscribers {
listSubscribers{
items {
id
name
industry {
name
}
}
}
}
If i run ListSubscribers query on appsync console, it gives me the desired result, like:
{
"data": {
"listSubscribers": {
"items": [
{
"id": "d04d6ef4-95bf-4b01-9a6a-13f550dbfa8f",
"name": "John Doe",
"industry": {
"name": "Real Estate"
}
},
{
"id": "96fa3e60-fdcf-4a6d-a3b6-72ec2c4701d1",
"name": "Jane Doe",
"industry": {
"name": "Ecommerce"
}
},
{
"id": "413dd506-afd4-474e-a850-54a39eb1eeeb",
"name": "John Doe",
"industry": {
"name": "Real Estate"
}
}
]
}
}
}
But if I run ListIndustries query, it does not give me the list of subscribers in that industry, like:
{
"data": {
"listIndustries": {
"items": [
{
"id": "b904d8f3-b504-48e0-b28f-0f9ac1742186",
"name": "Real Estate",
"subscribers": {
"items": []
}
},
{
"id": "167b87f2-3342-4390-80af-df53ba3c6f73",
"name": "Ecommerce",
"subscribers": {
"items": []
}
}
]
}
}
}
Need someone who can help me out with this.
I will need a bit more information to be sure but it looks like the Industry.subscribers resolver may be misconfigured. Your query expression currently specifies:
"query": {
"expression": "#connectionAttribute = :connectionAttribute",
"expressionNames": {
"#connectionAttribute": "id"
},
"expressionValues": {
":connectionAttribute": {
"S": "$context.source.id"
}
}
}
// There is no "index" so this is trying to query the primary index.
Which says, "Query the primary index where the 'id' = $ctx.source.id". Based on the objects you pasted, it looks like your Subscriber objects use $util.autoId() and thus the subscriber 'id' will never equal the industry 'id'. If using the Amplify CLI's #connection directive, a GSI will have been created on the Subscriber table with a hash key called 'subscriberIndustryId' by default. The Industry.subscribers resolver should query that index where the "subscriberIndustryId = $ctx.source.id". If you are not using the CLI and #connection, you can also implement this pattern yourself.
E.G. this should do the trick:
"query": {
"expression": "#connectionAttribute = :connectionAttribute",
"expressionNames": {
"#connectionAttribute": "subscriberIndustryId"
},
"expressionValues": {
":connectionAttribute": {
"S": "$context.source.id"
}
}
},
"index": "gsi-IndustrySubscribers"
I missed index in Industry.subscribers resolver. Adding it fixed the problem.

aws appsync connection does not bring back items from all models

I created a schema using the amplify cli and everything works as expected. The problem is when i try to perform a query on the events model it brings back comments as being null even though the event has comments. What confuses me more is when i query the comments alone they bring back their respective events but same thing does not work when i query for events. This is my schema below:
type Event #model {
id: ID!
title: String!
latitude: Float!
longitude: Float!
startDate: String!
endDate: String!
description: String!
coverUrl: String!
locationName: String!
Owner: User! #connection
attendies: [User!] #connection
photos: [Photo]
organization: Organization
comments: [Comment] #connection
}
type Comment #model {
id: ID!
user: User! #connection
event: Event! #connection
text: String!
}
The queries i performed are:
List Events
query listEvents {
listEvents {
items {
title
Owner {
username
}
comments {
items{
text
}
}
}
}
}
which brings back:
{
"data": {
"listEvents": {
"items": [
{
"title": "second Event",
"Owner": {
"username": "likono"
},
"comments": {
"items": []
}
}
]
}
}
}
and List Comments
query listComment{
listComments{
items{
text
event {
title
id
}
}
}
}
which brings back
{
"data": {
"listComments": {
"items": [
{
"text": "Second Comment Same User Same Event",
"event": {
"title": "second Event",
"id": "8bd6656b-b307-4e8f-ba65-84f75a4c2298"
}
}
]
}
}
}
Any help will be appreciated. Thanks.

Corresponding graphql-tag for a schema with nested inputs?

I'm following a tutorial (here:https://www.howtographql.com/graphql-js/5-authentication/) on graphql and came across a mutation with nested inputs.
How would I write the corresponding graphql-tag?
gql``
Schema:
type Mutation {
createUser(name: String!, authProvider: AuthProviderSignupData!): User
}
###########
## Inputs
###########
input AuthProviderEmail {
email: String!
password: String!
}
input AuthProviderSignupData {
email: AuthProviderEmail
}
Corresponding graphiql input:
mutation CreateUser {
createUser(name: "tester2", authProvider: {email: {email: "test#test.com", password: "password"}}) {
id
name
}
}
const mutation = gql`
mutation createUser($authProvider: AuthProviderSignupData!, $name: String!) {
createUser(authProvider: $authProvider, name: $name) {
id
}
}
`
const variables = {
"authProvider": {
"email": {
"email": "chakri#example.com",
"password": "123456789"
}
},
"name": "chakri",
}