Query multiple fields with same value [GraphQL][Amplify] - javascript

I'm creating an API with AWS Amplify and AppSync GraphQL. I Work on a Tinder like App.
I would like to search the same value in two fields for a Query. I've tried a lot of solutions, but none seems to work.
I have a User #Model which is connected to many Match via #connection
type User #model
#auth(rules: [{allow: public}])
{
id: ID!
email: String!
password: String
age: String!
name: String!
description: String
pickupLine: String
orientation: Orientation!
gender: Gender!
animal: Animal!
profilePicture: String!
pictures: [String]!
location: Location
numberOfSparksAvailable: Int!
matchs: [Match]
#connection(keyName: "byUser", fields: ["id"])
sparks: [Spark]
#connection(keyName: "byUser", fields: ["id"])
}
And I have a Match #Model which have a senderId field and a receiverId field
type Match #model
#auth(rules: [{allow: public}])
#key(name: "byUser", fields: ["receiverId", "senderId"], queryField: "matchByUser")
#key(name: "bySender", fields: ["senderId"], queryField: "sparkBySender")
#key(name: "byReceiver", fields: ["receiverId"], queryField: "sparkByReceiver")
{
id: ID!
status: MatchStatus!
matchType: MatchType
sender: User! #connection(fields: ["senderId"])
senderId: ID!
receiver: User! #connection(fields: ["receiverId"])
receiverId: ID!
answerFrom: Answer!
answerTo: Answer
chatRoomId: ID!
chatRoom: ChatRoom!
#connection(fields: ["chatRoomId"])
deletedAt: AWSDate
}
And and I don't find any way to make bySender #key look for both senderId and receiverId. I want to be able to have all the Matches for a User whether he's the receiver or the sender.
But when I make a Query to ListUsers I only get the Matches where the User is a receiver.
I've also tried to make multiple #connection but it is not allowed by Graphql-transformer.
I also tried to make an usersId: [ID!]! like that
type Match #model {
...
usersId: [ID!]!
users: [User!]!
#connection(fields: ["usersId"])
...
}
But It's also not allowed by graphql-transformer..
Has anyone a solution to get all the matches for a User?
Thanks a lot !

Related

Is it possible to have schema directives for input parameters?

I have already created a hasRole directive. I only want to include certain input parameters if the user has the admin role:
const typeDefs = gql`
type Article {
id: ID!
title: String!
content: String!
sponsor: String
}
input CreateArticleInput {
title: String!
content: String!
sponsor: String // include if #hasRole(role: "admin")
type Mutation {
createArticle(input: CreateArticleInput!): Article!
publishArticle(articleId: ID!): Boolean! #hasRole(role: "editor")
}
`
The goal is to provide the sponsor input parameter optionally if the user has the role "admin", otherwise, do not let the user include a "sponsor". I wonder if the native #include or #skip directives can be used in tandem with my custom #hasRole directive to achieve this? ..just a thought.
Is something like this possible? I am not even sure if this is allowed in the input type.

Unable to query Many to Many relationship in Amplify Datastore

I have 2 model with Many-to-Many Relationship. The 2 model is Order and Product. An Order will have many Product and Product will in many Order.
My Goal is : Given a orderID, get a list of productID in the Order
So I followed this Amplify guide to group the into OrderProducts , Order and Product like this schema.graphql
type Order #model #key(name: "byStore", fields: ["storeID"]) #auth(rules: [{allow: private, operations: [read, update, create, delete]}]) {
id: ID!
buyer_name: String
order_total_amount: String
products: [OrderProducts] #connection(keyName: "byOrder", fields: ["id"])
created_at: AWSTimestamp
}
type OrderProducts #model #key(name: "byOrder", fields:["orderID", "productID"]) #key(name: "byProduct", fields:["productID", "orderID"]) #auth(rules: [{allow: private, operations: [read, update, create, delete]}]){
id: ID!
orderID: ID!
productID: ID!
order: Order! #connection(fields: ["orderID"])
product: Product! #connection(fields: ["productID"])
}
type Product #model #key(name: "byStore", fields: ["storeID"]) #auth(rules: [{allow: owner, operations: [create, update, delete]}, {allow: public, provider: iam, operations: [read]}]){
id: ID!
product_name: String!
product_price: String!
created_at: AWSTimestamp
orders: [OrderProducts] #connection(keyName: "byProduct", fields:["id"])
}
But when I query the OrderProduct model like below, in order to get a List of Products by OrderID:
import { Product, OrderProducts } from '../models';
export const GetAllProductIdByOrderId = async (order) => {
return await DataStore.query(OrderProducts, op => op.orderID("eq", order.id)) // this is actual orderID
}
I get this error as a result:
Error: Invalid field for model. field: orderID, model: OrderProducts
What I tried:
Attempt 1
I tried to add a queryField named getOrderByOrderIDByProductID in OrderProducts like this:
type OrderProducts #model #key(name: "byOrder", fields:["orderID", "productID"], queryField: "getOrderByOrderIDByProductID") #key(name: "byProduct", fields:["productID", "orderID"]) #auth(rules: [{allow: private, operations: [read, update, create, delete]}]){
id: ID!
orderID: ID!
productID: ID!
order: Order! #connection(fields: ["orderID"])
product: Product! #connection(fields: ["productID"])
}
Then amplify push, amplify codegen models, after all this, I cant import getOrderByOrderIDByProductID in my file and get this error
warn Attempted import error: 'getOrderByOrderIDByProductID' is not exported from '../models' (imported as 'getOrderByOrderIDByProductID').
So I checked my model/index.js , it dont have getOrderByOrderIDByProductID exported. So dont know what else I can do.
Attempt 2
I go to AppSync console, I seen getOrderByOrderIDByProductID in my query section, then I tried to run this query:
query MyQuery {
getOrderByOrderIDByProductID(filter: {orderID: {eq: "8649a9da-9ea6-4a30-afe7-6b336a8f853d"}}) {
items {
order {
buyer_name
createdAt
id
}
}
}
}
Then I get the following output:
{
"data": {
"getOrderByOrderIDByProductID": null
},
"errors": [
{
"path": [
"getOrderByOrderIDByProductID"
],
"data": null,
"errorType": "MappingTemplate",
"errorInfo": null,
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "Expression block '$[query]' requires an expression"
}
]
}
I cant get any productID from the query and dont know what is the result mean.
I followed the suggestion mention in this github issue and reported in github as well, if you wanna to read a more detail version can read it here.
To summarize:
Only 1 goal: Given an orderID, give me a list of productID inside the Order.
And tell me what I doing wrong, if possible, give me an example. Cause I followed this example in amplify docs and still having this issue

Apollo client and graphQl query error : Variable '$where' expected value of type 'OrganizationWhereUniqueInput

Hi I'm making a backend server with GraphQL, Apollo client & Prisma. I'm trying to write a query where I get organization data back. The user who sends the query should get its organization data back based on their id. When running the query in playground I get this error.
error:
"message": "Variable '$where' expected value of type 'OrganizationWhereUniqueInput!' but got: {\"employees\":{\"id\":\"ckas83z13t9qk0992pucglc4k\"}}. Reason: 'employees' Field 'employees' is not defined in the input type 'OrganizationWhereUniqueInput'. (line 1, column 8):\nquery ($where: OrganizationWhereUniqueInput!) {\n ^",
I don't see what I did wrong. I'm still pretty new to it all. I tried to write the function in Query.js in different ways but no luck. Also, I still find the error messages you get in playground very confusing
schema:
type Query {
getOrganization: Organization!
}
type Organization {
id: ID!
name: String!
country: String!
street: String!
zipCode: Int!
houseNumber: Int!
addings: String
employees: [User!]
}
type User {
id: ID!
firstname:String!
lastname:String!
email: String!
services: [Service!]
organization: Organization!
}
query.js
function getOrganization(parent, args, context, info){
const userId = getUserId(context)
return context.prisma.organization({employees:{id:userId}})
}
// also tried this
/*
function getOrganization(parent, args, context, info){
const userId = getUserId(context)
return context.prisma.organization({where: {employees:{id:userId}}})
}*/
User.js
function services (parent, args, context){
return context.prisma.user({id: parent.id}).services()
}
function organization (parent, args, context){
return context.prisma.user({id: parent.id}).organization()
}
module.exports={
services,
organization
}
Organization.js
function employees(parent, args, context){
return context.prisma.organization({id: parent.id}).employees()
}
module.exports={
employees
}
Could anyone help me see what went wrong?
query in playground:
query{
getOrganization{
name
id
}}
HTTP HEADER:
{
"Authorization": "Bearer {contains user token }"
}
Just use OrganizationWhereInput instead of OrganizationWhereUniqueInput. It will return a list of organisations instead of a single result (might return an empty array), yet it should allow you to search for an organisation using an employee id.

GraphQL throwing syntax errors

I am developing the GraphQL Node tutorial, and am up to step 7.
https://www.howtographql.com/graphql-js/7-subscriptions/
I am getting a number of syntax errors from this code in my datamodel.prisma file:
directive #id on FIELD_DEFINITION
directive #unique on FIELD_DEFINITION
directive #createdAt on FIELD_DEFINITION
scalar DateTime
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!
}
But am still getting 'User' type [#6:1] tried to redefine existing 'User' type [#15:5] and 'Link' type [#24:1] tried to redefine existing 'Link' type [#6:5].
I am also not sure if I am declaring directives or scalars correctly as this is missing from the official tutorial.
Can anyone give any advice on how to sort these issues?
Schema.graphql:
type Query {
info: String!
feed(filter: String, skip: Int, first: Int, orderBy: LinkOrderByInput): Feed!
}
type Feed {
links: [Link!]!
count: Int!
}
type AuthPayload {
token: String
user: User
}
type User {
id: ID!
name: String!
email: String!
links: [Link!]!
}
type Vote {
id: ID!
link: Link!
user: User!
}
type Link {
id: ID!
description: String!
url: String!
postedBy: User
votes: [Vote!]!
}
type Subscription {
newLink: Link
newVote: Vote
}
type Mutation {
post(url: String!, description: String!): Link!
signup(email: String!, password: String!, name: String!): AuthPayload
login(email: String!, password: String!): AuthPayload
vote(linkId: ID!): Vote
}
enum LinkOrderByInput {
description_ASC
description_DESC
url_ASC
url_DESC
createdAt_ASC
createdAt_DESC
}
I had the same error this morning and I have a feeling it has something to do with caching. It went away when I renamed the variable. In your case, change all 'Link' definition/references to 'LinkTwo' and see if the error goes away. Same with 'User'... change it to 'UserTwo'. If it does, perhaps you can rename them back afterwards.
I haven't used Prisma before and only glanced at the tutorial but it looks like you're defining two User types; you have one in datamodel.prisma and Schema.graphql (I couldn't find two definitions of User in the tutorial). If they are read into the same instance, that'll be the reason why graphql thinks you are trying to redefine the User type. Remove one or, if it's applicable, change the second to extend type User should solve the syntax error.

Creating multi variable GraphQL query

I've been reading and trying alot of Stuff, but only using cURL as tools. Are there other ways run tests against an GraphQL endpoint?
So my problem is an mutation query with serveral variables. Here is part of my Shema:
type mutation {
oneComponentTypeCollected(userID: String!, password: String!, pageID: Int!,
Components: ComponentsInput!): Page
}
type Components {
ComponentType: ComponentType!
required: Int!
collected: Int!
}
type ComponentsInput {
id: String!
collected: Int!
}
type Page {
id: Int!
}
How do i call query the oneComponentCollected mutation?
What is expected is to set the collected value to 1 of the Component "inkpad_blue"
I tried the Following:
Variable syntax:
{"query":"mutation($input:ComponentsInput!) {oneComponentTypeCollected(userID: \"asd\", password: \"asd\", pageID: 1, input:$input){id}}","variables":{"input":{"id":"Inkpad_blue","collected":1}}}
as pure String:
mutation($input:ComponentsInput!) {oneComponentTypeCollected(userID: "asd", password: "asd", pageID: 1, input:$input){id}}
Both result in 500 HTTP errors.
I think your mutation should go like this
mutation{oneComponentTypeCollected(userID: "asd", password: "asd", pageID: 1, Components:{"id": "Inkpad_blue","collected": 1}){id}}
Try this in your graphiql

Categories