GatsbyJS - How to query longtext Contentful fields in GraphQL - reactjs

I ran into a problem querying a field of type "long text" from contentful.
I know the Contentful long text field is actually markdown. So I installed the gatsby-transformer-remark plugin, which I presumed I need.
Here's my GraphQL query:
query getStoreById($relativeUrl: String!) {
contentfulStore(relativeUrl: { eq: $relativeUrl }) {
relativeUrl
shopPageTitle
mainPageTextContent {
mainPageTextContent
}
}
}
The console still shows:
Objects are not valid as a React child (found: object with keys {childMarkdownRemark}).
Something to do with that error message.
Thanks!

The query will look something like:
query getStoreById($relativeUrl: String!) {
contentfulStore(relativeUrl: { eq: $relativeUrl }) {
relativeUrl
shopPageTitle
mainPageTextContent {
childMarkdownRemark {
html
}
}
}
}
If you haven't learned how to use GraphiQL yet, try opening it at localhost:8000/___graphql! It's your best friend for learning how to query your Contentful schema.

Related

How to add extra field to Algolia

I have a already made project having connection between Algolia + Gatsby + Contentful.
In which the algolia queries have
allContentfulProduct {
nodes {
objectID: id
productTitle: title
slug
seoTitle
node_locale
}
}
}
const queries = [
{
indexName: process.env.ALGOLIA_SEARCH_INDEX_NAME_PRODUCTS,
query,
transformer: ({ data }) => data.allContentfulProduct.nodes,
}
]
I need to add one extra field to algolia to filter through the search.
But when i add isVisibleInternalSearch to the const query the field is only visible when the gatsby build command in ran.
When there is any change in the contenful fields then the site is not able to find the algolia field.
allContentfulProduct {
nodes {
objectID: id
productTitle: title
slug
seoTitle
node_locale
isVisibleInternalSearch
}
}
}
I am having the same problem in the example site I created on netlify. Once the site was working fine but when there was any kind of change in contentful the field from the algolia disappeared.

Include mediaItems in GraphQL Wordpress query search

I have a headless WordPress installation, and using a React frontend to query posts with a search query of:
posts(where: {search: $searchStr}) {
nodes {
title
content
link
}
}
but would like to include media files in the search results as well. I'm able to query and log out the mediaItems from the following additional query:
mediaItems {
nodes {
title
sourceUrl
}
}
but unable to figure out how to include these in the search results. How do I combine the posts and mediaItems in the same search query and return all results based on the search string?
Updated with full query
The full query I'm using, passes the search query into the posts GraphQL query. Since mediaItems and posts are both top level in WordPress, how can I combine the two queries so that all posts and all media items are returned based on the search parameter?
query appQuery($searchStr: String) {
posts(where: {search: $searchStr}) {
nodes {
title
content
link
tags{
nodes {
name
}
}
}
}
mediaItems {
nodes {
title
sourceUrl
}
}
}
You can create another GraphQL type for that & nest it in your main type so that you can also query your data. Also add resolver for that data to be retrieved.
For example: let's say you have a blogging site & you have some posts. For that
type Post {
_id: String
title: String
credit: PostCredit # Name of nested type
}
type PostCredit {
authorId: String # You can also perform further nesting
publicationId: String
}

Reasoning with _raw and normal data in Gatsby, GraphQL and Sanity

I've just started using Gatsby with the Sanity headless CMS.
For the most part it's pretty straight forward; but knowing best practises for querying the data through GraphQL is still bothering me. How I'm doing it currently is just frantically clicking through my CMS structure in the GraphQL playground and finding what I want. This works but the lack of uniformity in this approach is making me uneasy.
For example, if I want a hero image that's in the CMS somewhere, i'll need to do something like:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
heroImage {
asset {
fluid(maxWidth: 1500) {
...GatsbySanityImageFluid
}
}
}
}
}
But if I want some PortableText block then I need to query the corresponding _raw field of whatever type. So, if my type was introText, Gatsby also provides a _rawIntroText. I'm only able to get the full PortableText from this _raw version of the data. Like this:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
_rawIntroText
}
}
It seems that, for some data you can use [Type], and sometimes you have to use _raw[Type].
There's not a great deal of documentation as to why this is the case. And I'm not sure if this is enforced via Sanity or Gatsby.
My question I guess would be, why does _raw[Anything] exist in the Gatsby and/or Sanity world, and how do people decide on which to use (other than just trial and error within the GraphQL playground and at runtime)?
This is coming from the gatsby-source-sanity plugin that Sanity built and maintains. Hopefully someone from Sanity can provide more context, but effectively the _raw[FieldName] entries return the original JSON data for the field. The unprefixed field (e.g. fieldName) is probably not what you want—it'll only contain bits of metadata about the data.
I tend to pull the _raw[FieldName] data and then just pass it straight into the #sanity/block-content-to-react component like so:
import React from "react"
import { graphql } from "gatsby"
import SanityBlockContent from "#sanity/block-content-to-react"
export default ({ data: { page } }) => (
<SanityBlockContent
blocks={page.textContent}
projectId={process.env.GATSBY_SANITY_PROJECT_ID}
dataset={process.env.GATSBY_SANITY_DATASET}
/>
)
export const query = graphql`
query SomePageQuery($id: String) {
page: sanitySomePage(id: { eq: $id }) {
textContent: _rawTextContent
}
}
`
Note that I'm using GraphQL aliasing to continue to refer to the field as textContent in my component rather than coupling the component to the specifics of this GraphQL schema.
You don't need to use Gatsby Image for Sanity images since they have their own image transformation pipeline anyways. Instead you can just fetch asset { _id } and then use #sanity/client like this to generate an image url:
import sanityClient from "#sanity/client"
import sanityImageUrl from "#sanity/image-url"
const client = sanityClient({
dataset: process.env.GATSBY_SANITY_DATASET,
projectId: process.env.GATSBY_SANITY_PROJECT_ID,
useCdn: true,
})
const builder = sanityImageUrl(client)
builder.image({ _id: "..." }).width(400).dpr(2).url()

Filtering Queries from Prismic and GatsbyJS

Seeing some strange behavior querying a Prismic data source and filtering by a content relationship in my gatsby site. I"m trying to create a page filtering some products based on the category passed into this page. Reading both the Prismic and Gatsby docs, i should be able to filter the data with the where clause but i get this error when i try to build
error Unknown argument "where" on field "allPrismicModel" of type "Query"
Below is the relevant sections of the query
query getProducts($uid: String) {
allPrismicModel(where: { system_category: $uid }) {
edges {
node {
data {
system_category {
uid
}
...other fields here...
}
}
}
}
}
Anybody ever encountered this or know how to resolve it?
where doesn't exist in Gatsby. I'd highly recommend using GraphiQL (under localhost:8000/___graphql) to see what you can do. There is also this doc showing all possibilities: https://www.gatsbyjs.org/docs/graphql-reference/
It'll probably will be in the end (untested):
filter: { system_category: { eq: $uid } }
allPrismicModel(filter: { system_category : { eq: $uid } }) {
edges {
node {
data {
system_category {
uid
}
...other fields here...
}
}
}
}
}
This is a more common way to run that query

Why I got error: Cannot query field xx on type "Query"?

Although I copied and pasted the graphQL query from the GraphiQL tool after I tested it at GraphiQL successfully , the query returned with an error when I tried it in Apollo client within a reactJS app:
[GraphQL error]: Message: Cannot query field "allStudents" on type "Query"., Location: [object Object], Path: undefined
Here is my implementation:
const link = createHttpLink({
uri: 'http://localhost:8000/graphql',
fetchOptions: { method: "POST" }
});
const client = new ApolloClient({
link: link
});
const GET_STUDENTS = gql`
query getStudents($schoolID: Int!){
allStudents(schoolId: $schoolID){
pickUpLat
pickUpLng
}
}
`;
client
.query({
query: GET_STUDENTS,
variables: { schoolID: 1 }
})
.then(result => console.log(result));
What could be wrong? here is the correct response that I expected:
{
"data": {
"allStudents": [
{
"pickUpLat": 31.9752942479727,
"pickUpLng": 35.8438429235775
},
{
"pickUpLat": 31.9754545979993,
"pickUpLng": 35.8437478537235
}
]
}
}
EDIT
I get expected results using GraphiQL:
EDIT2
I tried to compare the payload between my request and GraphiQL request:
My request's payload: ( it has __typename which I don't know why )
{"operationName":"getStudents","variables":{"schoolID":1},"query":"query getStudents($schoolID: Int) {\n allStudents(schoolId: $schoolID) {\n pickUpLat\n pickUpLng\n __typename\n }\n}\n"}
GraphiQL request's payload:
{"query":"query getStudents($schoolID: Int!){\n allStudents(schoolId: $schoolID){\n pickUpLat\n pickUpLng\n }\n}","variables":{"schoolID":1},"operationName":"getStudents"}
So, they are almost identical, Any idea?
The fault with my query was that I didn't download the new schema.
You can download the schema by using: apollo schema:download --endpoint=http://localhost:8080/graphql schema.json
replace http://localhost:8080/graphql with your server endpoint
You can see more at https://www.apollographql.com/docs/ios/downloading-schema/
In my case, I had defined a query which didn't require any parameters and it would return an array of objects:
myBasicQuery: [BasicAnswer]
type BasicAnswer {
name String
phone String
}
I was getting the error: Cannot query field \"BasicAnswer\" on type \"BasicAnswer\" when I declared it like this:
query myBasicQuery {
BasicAnswer {
name
phone
}
}
Leaving only the fields of BasicAnswer fixed the issue:
query myBasicQuery {
name
phone
}
For anyone else who might be searching for this problem, make sure you're importing ApolloClient from apollo-client package and not other packages.
For anyone that follows apollo-client has now been sunset, in favour of #apollo/client
Here is how you should be constructing a query
Updated #graphql-codegen/cli package to latest version(2.6.2) and it's working fine.
For anybody who use hasura also.
Problem was
query: query_root
# query: Query # wrong value before upgrade
mutation: mutation_root
subscription: subscription_root
}```
Take a look at your entity, it may be missing the #Field() annotation.
Example:
#PrimaryGeneratedColumn()
id: string;//Will not be mapped by GraphQL and you will get OP's error
#Column()
#Field()
name: string;//Will be mapped by GraphQL and you will not get OP's error
This also happens, if you have fragmented your graphqls files and you forgot to define it in codegen.ts.
(java-project)/src/main/resources:
schema.graphqls
search.graphqls
(angular-project)/codegen.ts
const codegen: CodegenConfig = {
overwrite: true,
// add wildcards here, to read all files:
schema: "../projectname/src/main/resources/graphql/*.graphqls",
documents: './src/app/core/graphql/*.ts',
generates: {
....
}
}
If you see this issue in the GraphiQL interface, you may need to merely refresh the page, which downloads the new schema and the error goes away.

Resources