Send an enum to graphql API from react app - javascript

I have an input (attached image) that I need to send to the graphql api from react application.
I am using below code to send this object and enum with init to graphql api
Reactjs Code
const RequestActionEnum = {
NEW: 'New',
UPDATE: 'Update',
ARCHIVE: 'Archive'
}
LocalCodeMutation({
variables: {
data: {
id: null,
city: values.jurisdiction,
country: values.country,
description: values.description,
edition: values.edition,
name: values.codeName,
note: 'test',
requestType: RequestActionEnum.NEW, // this is where i am sending enum value to api
state: values.state
}
}
});
Below code is where I am calling the mutation
const [LocalCodeMutation] = useMutation(LOCALCODE_MUTATION, {
refetchQueries: () => [
{ query: GET_LOCALCODES },
],
});
export const LOCALCODE_MUTATION = gql`
mutation LocalCodeMutation($data: LocalCodeRequestParamsInput) {
localCodeMutation(data: $data) {
ok
errors
localCodeInsertedId
}
}
`;
I am getting this error when I send to the API:
Error: GraphQL error: Variable $data got invalid value.
How can I send enum value to graphQL api from react component.
Could any one please suggest any ideas on this?

The enum values for RequestActionEnum are
NEW
UPDATE
ARCHIVE
If you were using this enum as a literal (not a variable), you would write it like this:
{
someField(someArgument: NEW)
}
Similarly, if you're using variables, you would use "NEW". Instead, you're using "New", which is not a valid enum value for this particular enum.
FWIW, if you actually read through to the end of the error, it would tell you as much as well.

Related

How to resolve a GraphQL DateTime field receiving '0000-00-00' and throwing error?

I have a similar to this question, however I don't see how it could be resolved using this other syntax currently in my Apollo project.
The issue is '0000-00-00' values coming from SQL db to my Apollo GraphQL server, thus throwing errors of invalid DateTime type. I'd like to write a resolver for the datetime field in question, like:
import gqlDate from 'graphql-iso-date';
const MyType = new gql.GraphQLObjectType({
name: 'Type',
description: 'This is a GraphQL type.',
fields: () => {
return {
datetime: {
type: gqlDate.GraphQLDateTime,
description: 'The datetime field of my type.',
resolve: (record) => {
return record === '0000-00-00 00:00:00' ? null : record;
}
}
};
}
});
However I cannot adjust this example to this other syntax my project is setup to:
import { gql } from 'apollo-server'
export const schema = gql`
extend type Query {
users(id: ID): [User!]
}
type User {
id: ID!
first_name: String!
middle_name: String
birthday: String!
}
import graphqlFields from 'graphql-fields'
export const usersResolver = {
Query: {
users: async (_, params, context, info) => {
const requestedColumns = Object.keys(graphqlFields(info))
return context.dataSources.db.getUsers(params, requestedColumns)
},
},
}
I played around with adding something like this to the resolver, but I'm not sure if it's the right thing to do and how exactly to implement it. Since the field resolves to Scalar, my guess is the below code won't be reached.
birthday: (parent, params, context, info) => { ... },
I also tried adding a separate query for the field, but am not sure how to connect it to the original users one.
My final resort is to just query the birthday as String and handle it on the front end, but that seems to be totally inappropriate compared to resolving it in GraphQL.

how to create apollo client query with custom types

I have to do a query and I have to pass a nested variable.
Below is the working query when I use apollo graphql client interface. It is giving me expected result. Below is the working query
query($input: MyProductInput!){
MyProductCategories(input: $input){
id,
name
}
}
Variable which i am passing
{
"input": {
"locale": "ENG"
}
}
MyProductInput type look like this at SERVER
type MyProductInput {
locale: Locale!
}
enum Locale {
IND
AUS
ENG
}
when I try to call the same query from my React App, it is giving me error, It says 400 bad request. My React query look like this.
const PRODUCT_LIST = gql`
query ($locale: String!) {
MyProductCategories(input: {locale: $locale}){
id,
name
}
}
`;
const { loading, error, data } = useQuery(PRODUCT_LIST, {
variables: {
"input": {
"locale": "ENG"
}
},
});
How can i convert my react query to accommodate custom types??
Note: I am using JavaScipt not Typescript at Front-end side
I got the answer. I just had to do this $input: MyProductInput! within query and pass $input to MyProductCategories. Below is working example.
const PRODUCT_LIST = gql`
query ($input: MyProductInput!) {
MyProductCategories(input: $input){
id,
name
}
}
`;
React Query using hooks
const { loading, error, data } = useQuery(PRODUCT_LIST, {
variables: {
"input": {
"locale": "ENG"
}
},
});
No need to worry about custom types as it is already there at server. Just pass is as it is and set the variables
Take a look in the docs:
https://www.apollographql.com/docs/react/api/react/hooks/
And can you see more information about the error message you get back?

Mock Relay-style pagination with Apollo Server

I have a mock server using Apollo Server to return GraphQL responses. One of the queries is to get teams which has an array of metrics (see schema below):
const mocks = {
Query: () => ({
teams: (/*parent, args, context, info*/) => teamsFixture,
}),
};
const graphServer = new ApolloServer({ typeDefs: schema, mocks });
graphServer.applyMiddleware({ app });
And my query used to be (fields redacted):
teams {
bpxId
metrics {
timestamp
}
}
The real (java) server has changed this to allow me to query (Relay style) only the first item in the metrics array as it wasn't performant:
teams {
bpxId
metrics(first: 1) {
edges {
node {
timestamp
}
}
}
}
With the response in this shape:
metrics: {
edges: [
{
node: [Team]
__typename: "TeamMetricsConnectionEdge"
}
]
__typename: "TeamMetricsConnection"
}
I want to add this capability to my Apollo Server mocks but not sure how?
New schema (relevant bits):
type TeamMetrics {
timestamp: Int
# etc
}
type TeamMetricsConnection {
edges: [TeamMetricsConnectionEdge]
pageInfo: PageInfo
}
type PageInfo {
hasPreviousPage: Boolean!
hasNextPage: Boolean!
startCursor: String
endCursor: String
}
type Query {
teams(bpxId: Int): [Team]
}
type Team {
bpxId: Int!
metrics(first: Int! = 5, after: String): TeamMetricsConnection
}
How can I adjust my mock response to handle Relay pagination? Thanks
You can use graphql-relay to create mock resolver results. This could be an easy way to create pagination for static mock arrays. Use connectionFromArray to wrap an array of mocks to automatically create an object structure that fits the connection type. It is possible to access all the field arguments in the mock similarly how you would do it in a real resolver and pass them into the function.
I am not sure if this works when you call the function on a MockList though. Pagination is a bit tricky as well if the length of the results changes all the time (the pageInfo.hasNextPage might be mixed up and you might violate a lot of assumptions that Relay has according to the spec). So it might be fine to start with a simple static array if that satisfies your mocking needs.

How to pass array of objects to the graphql query from js client

I want pass to server array of object throw graphql API.
my query on the schema:
export const schema = buildSchema(`
type Query {
statistics(
modelId: String
picksEnds: [PickEnd]
)
}: Statistics
type PickEnd {
end: String
limit: float
}
...
`)
my js based query on clients side:
const createStatisticsQuery = (...) => {
return `query {
statistics(
modelId: "${modelId}",
picksEnds: ${JSON.stringify(myEnds)}
) ...
but get error from graphql:
message: "Syntax Error: Expected Name, found String "end""
snippet from request payload:
{"query":"query {\n statistics(\n modelId:
\"5ca0f4afb88b3a2e006faa0d\",\n
picksEnds:
[{\"end\":\"home\"},{\"end\":\"draw\"},{\"end\":\"away\"},{\"end\":\"under\",\"limit\":0.5},{\"end\":\"over\",\"limit\":0.5},{\"end\":\"under\",\"limit\":1.5 ...
While GraphQL syntax is similar to JSON, you cannot use JSON inside a GraphQL document, which is what you're doing by calling JSON.stringify and then inserting the result into your template string.
What GraphQL expects:
[{end:"foo",limit:2.0}]
What using stringify does:
[{"end":"foo","limit":2.0}]
Since this syntax is not valid, an error is thrown. The easiest way to get around this issue is to utilize variables to provide the needed input, since variable values are provided as JSON.
# Note: Replace PickEndInput with whatever your input type is actually called
query StatsQuery($id: String!, $ends: [PickEndInput!]!) {
statistics(modelId: $id, picksEnds: $ends) {
# ...
}
}
You can then construct a JavaScript object for the variables and pass it along to fetch, axios or whatever you're using to make your request. For example:
const variables = {
id: 'SOME_ID',
ends: [
{
end:'foo',
limit: 2.0,
},
],
}
const query = ...
fetch('SOME_ENDPOINT_URL', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ variables, query }),
})
Ideally, you'd want to use an existing client like Apollo to make these calls easier.

Add custom GraphQL resolvers and types into Prisma/Nexus schema

Using: TypeScript, Prisma, MySQL, GraphQLServer, ApolloClient, building schema this way:
const schema = makePrismaSchema({
// Provide all the GraphQL types we've implemented
types: [Query, Mutation, User, Post],...
And then:
const server = new GraphQLServer({
schema,
context: { prisma }
});
How to combine that with custom resolvers and types unrelated to the SQL?
(I would like to call some REST endpoint by the GQL as well)
While nexus was created to be used alongside prisma, it's really just a schema builder. You could easily use it to create a schema without even utilizing Prisma. For example:
export const User = prismaObjectType({
name: 'User',
definition(t) {
t.list.field('comments', {
type: 'Comment',
resolve(root, args, ctx) {
return getComments();
},
});
},
})
export const Comment = prismaObjectType({
name: 'Comment',
definition(t) {
t.string('body');
},
})
Here getComments can return an array of comment objects, or a Promise that resolves to one. For example, if you're calling some other API, you'll normally return a Promise with the results of the call. As shown above, the resolver exposes the parent value, the field's arguments and a context object -- you can use any of this information in determining how to resolve a particular field.

Categories

Resources