Defining JSON/Object type in graphql-tag - graphql

I'm kinda new to Apollo gql, just wondering if anyone know if its possible to define Object class in graphql-tag?
export const CREATE_STYLE = gql`
mutation styleCreate(
$formID: String!
$fontFamily: Object //how do you define object/JSON object?
) {
styleCreate(
formID: $formID
fontFamily: $fontFamily
) {
styleID
}
}
`;

First, if the input type is an object I would recommend to define that on the server as a input type.
In my setup I'm using:
export const createUser = gql`
mutation createUser($user: UserCreate) {
create(input: $user) {
name
email
}
}
where "UserCreate" is an interface that looks like:
export interface UserCreate {
// The user name.
name: string,
// The user email address.
email: string,
};
You can manually create the interface, but I would suggest to use apollo codegen that gives you all the input types you need.

Related

Understanding React-Relay Connections in the Context of Type-GraphQL

The below code excerpt comes from the React-Relay docs on Rendering Connections. I am wondering if someone could provide me with an example of what the underlying schema definition (using `type-graphql for annotations/decorations) would look like.
const {graphql} = require('RelayModern');
const userFragment = graphql`
fragment UserFragment on User {
name
friends(after: $cursor, first: $count)
#connection(key: "UserFragment_friends") {
edges {
node {
...FriendComponent
}
}
}
}
`;
Would it look something like the following? With attention paid to the UserType type definition, and especial attention to the friends field. I am also hoping if anyone could turn my attention to a more elaborated upon example/boilerplate to help me understand what is compliant with the Relay specification. Some examples I am after:
How to type the return type of a Query if I intend one of the Query's resolved fields to be a Connection type? And what would this look when written as a fragment.
How to type the same scenario as above, except now the return type is an iterable of the original return type?
#ObjectType({ implements: [Node] })
export class UserType extends Node {
#Field()
name: string
#Field()
friends: UserConnection
}
const User = createUnionType({
name: 'User',
types: () => [UserType] as const,
resolveType: value => {
// if ('code' in value) {
// return Error
// }
return UserType
}
})
#ObjectType()
export class UserEdge extends EdgeType('report', User) {}
#ObjectType()
export class UserConnection extends ConnectionType<UserEdge>(
'user',
UserEdge
) {
}

KeystoneJS relationships, how can I connect using an array of ids

I am using the new version Keystone Next and I am trying to connect multiple items at once using an array of ids. It seems connect supports that, accepting an array of objects.
const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
$userId: ID!
$wordId: ID!
) {
updateUser(id: $userId, data: {
wrongAnswers: {
connect: [{id: "idblabla"}, {id: "idblabla2"}]
}
}) {
id
}
}`;
But what I just can't seem to figure out is how do I pass this array of ids as a variable to my mutation.
I understand that I would need to create a new type? The documentation is still unfinished, so there is nothing on that yet.
I have also tried using string interpolation to form my query, but it seems that it's not a thing in GraphQl.
This is more of a GraphQL question than a KeystoneJS but one but to head to the right direction here you'd need to change your query to something like below:
const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
$userId: ID!,
$ids: [UserWhereUniqueInput!]!
) {
updateUser(id: $userId, data: {
wrongAnswers: {
connect: $ids
}
}) {
id
}
}`;
And then map your array of ids to an array of objects with id fields.
There is a better method:
const FINISH_VOCABULARY_QUIZ_MUTATION = gql`
mutation FINISH_VOCABULARY_QUIZ_MUTATION(
$userId: ID!,
$data: SomeAPIDefinedMutationUniqueInput
) {
updateUser(id: $userId, data: $data)
id
}
}`;
This way you:
don't have to define types for internal arguments ($wordsIdWrong: [WordWhereUniqueInput]);
can reuse/share this mutation - import it from some, common for queries, place (dir) - just call it with different data variables;
easier for reading/maintenance;
PS. To be honest, there should be some specific [to quizes] mutation (don't use userUpdate for that), with user (or better quiz) id defined within SomeAPIDefinedUniqueInput.

TypeGraphQL createUnionFunction with parameter

I'm trying to implement an extension of typegraphql's createUnionType() function to where I can pass in a class/ObjectType instead of hardcoding, and it will return a union type of both.
What I have so far doesn't work but I feel like it's possible. Could anyone provide any insight? Maybe it's not possible?
typedefs
import { ObjectType, Field, createUnionType, ClassType } from "type-graphql";
#ObjectType()
export default class MutationSuccess {
#Field()
success: boolean = true;
}
// Doesn't work
export const MutationResponse = (objectType: ClassType) => createUnionType({
name: 'MutationResponseType',
types: () => [MutationSuccess, objectType],
})
How I'm trying to use it in my resolver
#Resolver()
export default class RelationResolver {
#Mutation(() => MutationResponse(Relation), { description: 'follow user' })
async follow(
#Arg('relationInput') relationInput: RelationInput
): Promise<Relation | MutationSuccess> {
// do some stuff
}
}
error
UnhandledPromiseRejectionWarning: Error: Cannot determine GraphQL output type for follow
The Relation class need to be decorated with #ObjectType and the union type name has to be unique.

how to use enum in apollo-client?

the enum define in OrderTypesEnum.gql
enum OrderTypes {
full_buy
pink_buy
}
import OrderTypesEnum.gql file
import OrderTypes from '#/graphql/OrderTypesEnum.gql'`
but, How to get enum in code ?
I use OrderTypes.full_buy get some error:
self.$apollo.mutate({
mutation: createOrder,
variables: {
subjectId: self.subject.id,
types: OrderTypes.full_buy
}
})
Mutation createOrderMutation error: Invariant Violation: Schema type definitions not allowed in queries. Found: "EnumTypeDefinition"
the inspect of OrderTypes type enum
Prerequisites:
< SomeEnumType > is defined in GraphQL schema (server side, no client configuration needed)
Let's assume we have:
enum SomeEnumType {
OPTION1,
OPTION2,
OPTION3
}
Apollo Client should be configured appropriate way and connected with the GraphQL API.
Then on the client side:
export const OUR_MUTATION = gql`
mutation ourMutation($foo: SomeEnumType){
ourMutation(foo: $foo){
bar
}
}
`
Only by doing this, we can pass an enum as a variable in our query or mutation. For example, with useMutation hook we can now mutate as follows:
const [ourMutation] = useMutation(OUR_MUTATION, {
variables: {
foo: "OPTION2"
},
Since the type definition in gql tag equals the definition in Schema, GraphQL recognizes a variable as an enum type despite giving it as a string.
If we want to pass an enum to variables using typescript enums we can do it as follows:
enum SomeEnumType {
OPTION1 = 0,
OPTION2 = 1,
OPTION3 = 2
}
const [ourMutation] = useMutation(OUR_MUTATION, {
variables: {
foo: SomeEnumType[SomeEnumType.OPTION1]
},
UPDATE: String enums and type generation
Personally, I recommend using string enums if possible. The usage of string enums is more straightforward.
enum SomeEnumType {
OPTION1 = "OPTION1",
OPTION2 = "OPTION2",
OPTION3 = "OPTION3"
}
...
...
variables: {
foo: SomeEnumType.OPTION1
}
For next-level coding, enum types, and all other type definitions can be automatically generated to the frontend with graphql-codegen. I really recommend using this approach, since backend schema updates and additions directly can be directly reflected in your frontend code revealing bugs and helping you code faster and more reliable.
As the error message is suggesting, Schema type definitions not allowed in queries., you can't add an enum definition in an operation document (ExecutableDefinition). You can only have operations (query, mutation, or subscription), or fragments definitions. That is, this is invalid:
enum OrderTypes {
FULL_BUY
PINK_BUY
}
mutation createOrderMutation {
...
}
If you want to define a local enum on your client, you can use the typeDefs property during ApolloClient initialization:
const client = new ApolloClient({
cache,
typeDefs: gql`
enum OrderTypes {
FULL_BUY,
PINK_BUY
}
`,
});
And then you'll be able to see the OrderTypes enum on client-side introspection (i.e Apollo extension).
Pay attention to the client-side highlight: if you try to send a request with this enum for a non-client field (i.e without the #client directive) and it makes through your server, you'll get a schema error saying that the enum type does not exist, unless you define it on your backend.

How to pass multiple string parameter in GraphQl query using apollo client

How can I create query with multiple string parameters. I have used apollo client and created query as follow. But xcode didnot allow to build.
mutation changePassword($oldPass: String, $newPass: String) {
changePassword(old_password: $oldPass, new_password: $newPass) {
}
}
I think you are missing the input key
mutation changePassword($oldPass: String, $newPass: String) {
changePassword(input: {old_password: $oldPass, new_password: $newPass}) {
}
}
also, it will be helpful if you post the whole mutation code, one example could be:
import gql from 'graphql-tag';
import client from '../client';
function ChangePassword(parameters){
return client.mutate({
mutation: gql `
mutation changePassword($oldPass: String!, $newPass: String){
changePassword(input: {old_password: $oldPass, password: $newPass}){
user {
email
firstName
lastName
}
}
}
`,
variables: {
oldPass: parameters.oldPass,
newPass: parameters.newPass,
}
})
};
export default ChangePassword;
where user is your payload

Resources