How to define an optional field in graphQL fragment for query - graphql

Tha database for that queries comes up to a set of YAML files in a folder.
Using GatsbyJS theses files are collected and are available by graphQL requests.
Not all source files defines a label field.
Is it possible to return a default or empty value for that field when missing?
Actually I get following error:
Cannot query field "label" on type "EngagementsYamlTo".
This is my query:
{
stable: allEngagementsYaml(filter: {stable: {eq: true}, to: {}}) {
edges {
...engagementNode
}
}
unstable: allEngagementsYaml(filter: {stable: {eq: false}}) {
edges {
...engagementNode
}
}
}
fragment engagementNode on EngagementsYamlEdge {
node {
heading
description
iconClass
stable
to {
href
label
}
}
}

Hm ... that was not a problem of the query.
None of the source files had a label field, so that schema was never touched. Having at least 1 file with label field will return a valid response.
Clarified for this case!

Related

How to load image in Gatsby GraphQL query

I have small SQLite database with products, that have relative paths to images.
I'd like to include these images to my page. I'm trying to use this query:
query {
allContent {
nodes {
Category
Description
Price
ProductID
Title
ImageURI {
childImageSharp {
gatsbyImageData(width: 200)
}
}
}
}
}
But I have this error:
Field "ImageURI" must not have a selection since type "String" has no subfields.
This can happen if you e.g. accidentally added { } to the field "ImageURI". If you didn't expect "ImageURI" to be of type "String" make sure that your input source and/or plugin
is correct.
However, if you expect "value" to exist, the field might be accessible in another subfield. Please try your query in GraphiQL and use the GraphiQL explorer to see which fields
you can query and what shape they have.
It is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned
"dummy content". Visit our docs to learn how you can define the schema for "undefined":
https://www.gatsbyjs.com/docs/reference/graphql-data-layer/schema-customization#creating-type-definitions
As I understand, I should convert String to File in my query. Is it right? If yes, how to do that?
Full code & repo to reproduce: https://github.com/vladd11/gatsby-test/blob/master/src/pages/index.js
Just query allFiles outside of allContent nodes. Like:
allFile {
edges {
node {
relativePath
childImageSharp {
gatsbyImageData(width: 200)
}
}
}
}
Don't forget to add new source of data to Gatsby Config:
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/static`, // Directory with your images
name: "images",
},
}
Find image in this directory using relative path, then load image dynamically:
getImage(data.allFile.edges.find(value => value.node.relativePath === product.ImageURI).node)
Use GatsbyImage to show this image:
<GatsbyImage alt={product.Title} image={Image}/>

sort content by tag in Gatsby with Conteful API

In Contentful, I create a content with few media pictures. The pictures have two different tags boxon and attaqueGenetique. I want to sort the slideshow by using tags I've added for each media, but I don't find the way to do that. There is an example on the website Gatsby, but is not really clear and my try failed to make it mine.
The example from Gatsby
query FilterByTagsQuery {
allContentfulNumber(
sort: { fields: contentful_id }
filter: {
metadata: {
tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } }
}
}
) {
nodes {
title
integer
}
}
}
I've supposed I must transpose thise code to mine where
allContentfulNumber become allContentfulDiaporama, and
metadata: {
tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } }
}
become
metadata: {
tags: { elemMatch: { contentful_id: { eq: "boxon" } } }
}
but when I try to compile the console return
56:5 error Field "metadata" is not defined by type "ContentfulDiaporamaFilterInput" graphql/template-strings
I don't know where catch metadata from media when it's imported in content... but I'm very beginner with graphql and Contentful. If there is a solution, that's can make my day happy !!!
metadata in Gatsby's example is a GraphQL node valid in their data structure, if yours hasn't it simply don't use it or it will break the code since it's not a valid custom type.
The problem in your query, besides using an invalid field (metadata) is that you are using an elemMatch filter, comparingcontentful_id (number) to boxon (string), so it will never work in your scenario (it works in Gatsbys' because it's the same type). In your case, you may want to use in (for arrays) or eq (for single values). Check the available list at: https://www.gatsbyjs.com/docs/graphql-reference/#filter
As far as I understand your question, it seems that you want to split your diaporama data in two different nodes, the ones that contain boxon and the ones that contain attaqueGenetique. If so, you will need to create different nodes by aliasing them:
query FilterByTagsQuery {
boxon: allContentfulDiaporama(
sort: { fields: contentful_id }
filter: {
metadata: { tags: { in: ["boxon"] } }
}
) {
nodes {
#your data/fields here
}
}
attaqueGenetique: allContentfulDiaporama(
sort: { fields: contentful_id }
filter: {
metadata: { tags: { in: ["attaqueGenetique"] } }
}
) {
nodes {
#your data/fields here
}
}
}
Test the query in the GraphiQL playground, available at localhost:8000/___graphql where it will be much more intuitive for you to add or remove filters and see the available nodes.
The snippet above will generate two different data structures based on the tags aliased. With this: boxon: allContentfulDiaporama, you are aliasing the result of allContentfulDiaporama in boxon so in your page, you will be able to access directly props.data.boxon and props.data.attaqueGenetique respectively.
Keep in mind that the sort filtering method only works on dates or numeric values, in the case of strings, it will sort them alphabetically. So I'm assuming that your data has a contentful_id (I'm not sure how it will be helpful sorting by contentful_id).
According to this pull-request the enableTags feature was fixed in the cutting-edge release(5 days ago) so try to upgrade your plugin dependency.
It seems to be fixed in, according to this GitHub thread:
gatsby-source-contentful#7.5.0-next.0
Or in the next release.

Contentful GraphQL endpoint: how to retrieve all entries of a content type

{
Post {
name
}
}
While trying to retrieve all the entries on a content type, it only gives error of:
"Argument \"id\" of required type \"String!\" was not provided."
Since id field is required. How do I get all entries of a content type then?
Ref: https://www.contentful.com/developers/docs/references/graphql/
From docs here:
The produced Query object exposes two fields that you can use to query content of that type: one to fetch individual content documents (friendlyUser in the example) and another to do queries over all the content of the type (friendlyUserCollection).
So for any resource that you want to retrieve all entries of, you need to append Collection at the end of its id, then use items field to retrieve all entries. As in:
{
PostCollection {
items {
name
}
}
}
Apart from docs, you can also view all available resources at corresponding GraphiQL instance here, which could be pretty useful:
https://graphql.contentful.com/content/v1/spaces/{SPACE_ID}/explore?access_token={ACCESS_TOKEN}
Search or select Query to see all schemas:
Query a single id
I think you can try this in the GraphQL playgound
http://localhost:8000/___graphql
query PostById($id: String!) {
contentfulPost(id: { eq: $id }) {
name
}
}
and add a QUERY VARIABLE
{
"id": "my-awesome-id"
}
Query all the Posts
How do I get all entries of a content type then?
On the GraphQL playground, you should be able to do something like this
{
allContentfulPost {
nodes {
name
}
}
}

Graphql, return result only if record not null

Totally new in Gatsby (my app is build in here). Also new in Graphql but I go this project from a colleague and now I need to find a way to sort it out.
I have a query in graphql that looks as follow:
query MediasQuery {
allStrapiMedias(sort: { fields: [date], order: DESC }) {
edges {
node {
id
name
description
date(formatString: "Do MMMM, YYYY")
link
poster {
childImageSharp {
fluid {
src
}
}
}
file {
url
}
}
}
}
}
The issue I am facing is that the file record can exist or not, to be more accurate, if link record is empty, then I should find a file (this is how it's been build in Strapi).
If I have at least one record with file then the query run normally, but as soon as I deleted this record from database all the app crash.
How can I make that query to only return file if url is empty or null?
You are querying an object that will have one property (file) filled or not with an url. You just need to add that logic to your JavaScript and React code. When you will print the file, add the new logic, something like:
if (data.allStrapiMedias.edges.node.file) return <ComponentA/>
else return <ComponentB/>
I think that what you are looking for is something that the previous snippet. However, answering your question, you achieve it by adding filters to your query:
query MediasQuery {
allStrapiMedias(
sort: { fields: [date], order: DESC }
filter: { file: {url: {ne: null }}}
) {
edges {
node {
id
name
description
date(formatString: "Do MMMM, YYYY")
link
poster {
childImageSharp {
fluid {
src
}
}
}
file {
url
}
}
}
}
}
More details in GraphQL Query Options Reference.

How can I filter by uid of a linked document / relationship using the prismic graphql api?

I am trying to list a set of articles by their categories, by uid, and I'm assuming that I would have to use the where query, but I'm not able to get that to worked on linked documents.
The issue seems to be that where only accepts a string on a field, but in the case of a linked document you would need to dig down to the uid field.
I'm not sure if I'm using the wrong query, but struggling to find anything in the documentation to help me out.
I tried digging into the category object:
{
allDirectoryServices(
where: { category: { _meta: { uid: "developers" } } }
) {
edges {
node {
name
city
region
country
category {
...on DirectoryTaxonomy {
_meta {
uid
}
name
}
}
}
}
}
}
But that returns an error that it's expecting a string:
"message": "Expected type String, found {_meta: {uid: \"developers\"}}.",
{
allDirectoryServices(
where: { category: "developers"}
) {
edges {
node {
name
city
region
country
category {
...on DirectoryTaxonomy {
_meta {
uid
}
name
}
}
}
}
}
}
This returns no results, obviously.
I asked this question on the Prismic Slack group too, and got the answer from them:
In order to query by a Content Relationship / Link field like this, you need to use the document ID.
where: { category: "WBsLfioAABNUo9Kk" }
Unfortunately it isn’t possible to query by the UID (or any other field).
I imagine they will be updating their documentation soonish, as this isn't covered by it.
Thanks to the Prismic guys!

Resources