Multiple queries in a component for Gatsby - graphql

I'm using Gatsby to createPages and then in the createPage method I'm referencing a specific component for the page
createPage({
path: node.path.alias,
component: path.resolve(`./src/layouts/custom-page/custom-page.js`),
context: {
articleId: node.id,
authorId: node.relationships.field_author.id
},
})
Within the layout (custom-page.js) I'm trying to do 2 queries but it's not working for me. When I test this query in GraphiQL it works fine.
export const query = graphql `
query ($articleId: String!, $authorId: String!) {
article: nodeArticle(id: {eq: $articleId}) {
title
body {
value
}
path {
alias
}
}
author: nodePerson(id: {eq: $authorId}) {
title
path {
alias
}
}
}
`;
Within my component I would then expect to be able to access the data with either data.author.title or data.article.title.
Is it possible to do this in Gatsby?

Your query is seemed to be bit wrong or some missing in the query.
Query should look like.
export const query = graphql `
query Articles($articleId: String!, $authorId: String!) {
article: nodeArticle(id: {eq: $articleId}) {
title
body {
value
}
path {
alias
}
}
author: nodePerson(id: {eq: $authorId}) {
title
path {
alias
}
}
}
`;
Better to use the package graphql-tag.
Your query will look like.
import gql from 'graphql-tag';
export const query = gql`
query Articles($articleId: String!, $authorId: String!) {
article: nodeArticle(id: {eq: $articleId}) {
title
body {
value
}
path {
alias
}
}
author: nodePerson(id: {eq: $authorId}) {
title
path {
alias
}
}
}
`;

Related

Apollo client fragments not embedding data

This is the first time I've ventured into fragments and I can't see where I'm screwing up, but it definitely isn't working! In GraphiQL it's working fine:
query Tasks($taskIds: [String]!) {
tasks(taskIds: $taskIds) {
...taskDisplay
}
}
fragment taskDisplay on Task {
_id
name
description
status
children {
_id
}
}
Here's what's in my client app:
import { gql } from "#apollo/client";
export const TASK_FRAGMENT = gql`
fragment taskDisplay on Task {
_id
name
description
status
children {
_id
}
}
`;
export const TASKS = gql`
query Tasks($taskIds: [String]!) {
tasks(taskIds: $taskIds) {
...taskDisplay
}
}
${TASK_FRAGMENT}
`;
So, the server returns the data correct as I can see in the Network tab of Chrome, but the data received by the useQuery result is an empty object. What gives?
Using #apollo/client#3.2.0-beta.2 (I have downgraded to 3.1.0 with same results)
EDIT:
Adding more info. My code is about as simple as it could be using a hook. Here's what's happening:
import { useQuery, gql } from "#apollo/client";
import { TASK_FRAGMENT } from "../pages/task/queries";
const ROOT_TASK_QUERY = gql`
query Project($projectId: String!) {
rootTask(projectId: $projectId) {
...taskDisplay
}
}
${TASK_FRAGMENT}
`;
const useProject = ({ variables }) => {
return useQuery(ROOT_TASK_QUERY, {
variables,
});
};
export default useProject;
And this is just logging the query itself:
Your returned data is missing the __typename field

How to work around GraphQL error, field "x" must not have a selection since type "String" has no subfields

I am using Gatsby and GraphQL, and I am new to GraphQL.
I have the following schema definition:
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type MarkdownRemark implements Node {
frontmatter: Frontmatter
}
type Frontmatter {
title: String!
products: [Product]
}
type Product #dontInfer {
name: String!
price(price: Int = 1): Float
description: String
images: [ProductImage]
}
type ProductImage {
url: String
}
`;
createTypes(typeDefs);
};
Then on my page I use the following query:
query {
markdownRemark(fileRelativePath: { eq: "/content/pages/products.md" }) {
...TinaRemark
frontmatter {
title
products {
name
price
description
images {
url {
childImageSharp {
fluid(maxWidth: 1920) {
...GatsbyImageSharpFluid_withWebp
}
}
}
}
}
}
html
}
}
I then receive the following error:
Field "url" must not have a selection since type "String" has no subfields.
Does anyone have any suggestions on how to work around this error?
Also, what is childImageSharp? I'm wondering what the terminology is to define it. Is it a GraphQL "selector" or "function"?
It should be
query {
markdownRemark(fileRelativePath: { eq: "/content/pages/products.md" }) {
...TinaRemark
frontmatter {
title
products {
name
price
description
images {
url
}
}
}
html
}
}
Because you definition is
type ProductImage {
url: String
}
The url apparently has no sub fields.
For what it's worth (I don't know if this is related to your specific issue.) If your markdown path for the image file is invalid, GraphQL will return this error, interpreting the path as a string. I had this problem and it went away when I realized I had misspelled the path in the markdown.
productImage {
childImageSharp {
gatsbyImageData(width: 200)
}
}
I had a similar problem with returning a boolean. For me, instead of something like this
mutation {
someFunc(
memo: "test memo"
) {
success
}
}
I needed this
mutation {
someFunc(
memo: "test memo"
)
}

How to solve "mutation returning data null"?

i'm using apollo-server and want to learn graphql schema, queries and mutations but iam not getting correct resources for understing how mutation works and how to define mutation in resolvers
i have tried something like adding "mutation" similar to "query" in the resolvers but no use.
#schema
const typeDefs = gql`
type Book {
title: String
author: String
}
type Mutation {
addBook(title: String, author: String): Book
}
type Query {
getBooks: [Book]
}
`;
#resolvers
const resolvers = {
Query: {
getBooks: () => books
}
};
#querying in graphql playground
mutation{
addBook( title: "a sad love story",author:"pavan kalyan"){
title
author
}
}
#result i got
{
"data": {
"addBook": null
}
}
i want to get the title and author in the result same as the arguments iam passing in the query
and no error messages
You need to define the mutation in your resolvers:
const resolvers = {
Query: {
getBooks: () => books,
},
Mutation: {
addBook: (_, {input}) => {
// ... code to add book somewhere
const addedBook = insert(input.title, input.author);
return addedBook; // i.e. {title: input.title, author: input.author};
}
}
}

Nested query and mutation in type-Graphql

I found a feature in graphql to write nested query and mutation, I tried it but got null. I found the best practices of building graphqL schema on Meetup HolyJs and the speaker told that one of the best ways is building "Namespaced" mutations/queries nested, in this way you can write some middlewares inside the "Namespaced" mutations/queries and for get the Child mutation you should return an empty array because if you return an empty array, Graphql understand it and go one level deep.
Please check the example code.
Example in graphql-tools
const typeDefs = gql`
type Query { ...}
type Post { ... }
type Mutation {
likePost(id: Int!): LikePostPayload
}
type LikePostPayload {
recordId: Int
record: Post
# ✨✨✨ magic – add 'query' field with 'Query' root-type
query: Query!
}
`;
const resolvers = {
Mutation: {
likePost: async (_, { id }, context) => {
const post = await context.DB.Post.find(id);
post.like();
return {
record: post,
recordId: post.id,
query: {}, // ✨✨✨ magic - just return empty Object
};
},
}
};
This is my Code
types
import { ObjectType, Field } from "type-graphql";
import { MeTypes } from "../User/Me/Me.types";
#ObjectType()
export class MeNameSpaceTypes {
#Field()
hello: string;
#Field({ nullable: true })
meCheck: MeTypes;
}
import { Resolver, Query } from "type-graphql";
import { MeNameSpaceTypes } from "./MeNamespace.types";
#Resolver()
export class MeResolver {
#Query(() => MeNameSpaceTypes)
async Me() {
const response = {
hello: "world",
meCheck:{}
};
return response;
}
}
Result of code
query {
Me{
hello
meCheck{
meHello
}
}
}
--RESULT--
{
"data": {
"Me": {
"hello": "world",
"meCheck": {
"meHello": null
}
}
}
}
I got a null instead a meHello resolver. Where am I wrong?
Namespaced mutations are against GraphQL spec as they are not guarranted to run sequentially - more info in this discussion in GitHub issue related to your problem:
https://github.com/MichalLytek/type-graphql/issues/64

Gatsby graphql with regex as variable

I would like to use regex with graphql query variable.
This does't return results:
export const query = graphql`
query(
$episodes: String!
) {
episodes: allMarkdownRemark(
filter: { fields: { slug: { regex: $episodes } } }
) {
edges {
node {
id
}
}
}
}
`;
However, this would work:
export const query = graphql`
query() {
episodes: allMarkdownRemark(
filter: { fields: { slug: { regex: "/episodes/travel/" } } }
) {
edges {
node {
id
}
}
}
}
`;
what's wrong?
Passing regex via query arguments should work, see the screenshot below. Make sure you're passing in the regex as string, not the actual regex. Also, you'll need to escape the middle slash:
context: {
- episodes: /episodes\/traveller/ <-- doesn't work
+ episodes: /episodes\/traveller/.toString() <-- works
or episodes: "/episodes\\/traveller/" <-- also works
}
Try it out in one of the graphiQL embed in this page

Resources