Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WP ACF repeater with image bug #3009

Closed
craig-doyle-uk opened this issue Nov 23, 2017 · 13 comments
Closed

WP ACF repeater with image bug #3009

craig-doyle-uk opened this issue Nov 23, 2017 · 13 comments

Comments

@craig-doyle-uk
Copy link

Node version v6.7.0
Gatsby version 1.9.108

gatsby-config.js :

module.exports = {
  siteMetadata: {
    title: `Anchor Employee Rewards`,
    date : `Today`
  },
  plugins: [
    `gatsby-plugin-glamor`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
    {
      resolve: 'gatsby-source-wordpress',
      options: {
        baseUrl: 'anchor-admin.wearewhy.co.uk',
        protocol: 'http',
        hostingWPCOM: false,
        useACF: true,
        verboseOutput: true,
      }
    }
  ],
}

gatsby-node.js

const _ = require(`lodash`)
const Promise = require(`bluebird`)
const path = require(`path`)
const slash = require(`slash`)

exports.createPages = ({ graphql, boundActionCreators }) => {
  const { createPage } = boundActionCreators
  return new Promise((resolve, reject) => {
    graphql(
      `
        {
          allWordpressPage {
            edges {
              node {
                id
                slug
                status
                template
                acf {
                  hero_image {
                    source_url
                  }
                  hero_intro
                  benefit_list {
                    title
                    intro
                    content
                    article_image {
                      source_url
                    }
                  }
                }
              }
            }
          }
          wordpressPage(title : {eq : "Home"}) {
            acf {
               hero_image {
                  source_url
              }
              hero_intro
              page_menu {
                page {
                  post_title
                  post_name
                  }
               }
            }
         }
        }
      `
    )
      .then(result => {
        if (result.errors) {
          console.log(result);
          reject(result.errors)
        }
        // Create Page pages.
      
        resolve()
      })
  })
}

pacjage.json :

{
  "name": "gatsby-starter-hello-world",
  "description": "Gatsby hello world starter",
  "license": "MIT",
  "scripts": {
    "develop": "gatsby develop",
    "build": "gatsby build",
    "serve": "gatsby serve"
  },
  "dependencies": {
    "gatsby": "^1.9.102",
    "gatsby-image": "^1.0.24",
    "gatsby-link": "^1.6.22",
    "gatsby-plugin-glamor": "^1.6.8",
    "gatsby-plugin-sharp": "^1.6.20",
    "gatsby-plugin-typography": "^1.7.10",
    "gatsby-source-wordpress": "^2.0.36",
    "gatsby-transformer-sharp": "^1.6.13",
    "react-helmet": "^5.2.0",
  }
}

We have an issue whereby our site works correctly when we add a page with a repeater that includes maybe 3 or 4 images (in the above case the field is named article_image). When we then create a couple more similar pages the site stops working with the following error in our gatsby-node.js graphQL results callback.

GraphQLError: Field "article_image" must not have a selection since type "Boolean" has no subfields.

We can see when removing source_url as suggested that image just has a value of null
If we delete the article_image acf field and create a new one with another name the site works again until we have added a few images and then the same issue occurs on the new field. We've tested a few things on the backend such as increasing the memory for WP as we thought it could be related to WP but it doesn't appear to be as the images are still displaying correctly in the CMS- but are not accessible from the Gatsby app.

@craig-doyle-uk
Copy link
Author

The data for images in the ACF repeater field are still visible via the REST API, but are being stripped out in the app's GRAPHQL- I think this is occurring in the normalise.js mapEntitiesToMedia function but I'm not yet sure. Is there any way of resolving this?

@craig-doyle-uk
Copy link
Author

I'm closing this issue as it appears to be the result of a particular image file, or group of images- we can track their urls and data through the various normalise.js functions without an obvious reason for them causing a problem- but they do. When we remove and replace these image files the site runs correctly on both develop and build.

@craig-doyle-uk
Copy link
Author

craig-doyle-uk commented Dec 6, 2017

I have realised that this is not as above mentioned the result of particular images. My site was working correctly until I added another AFC component which contained images. This then not only caused a graphql error on the new ACF field but also some of the previously working ones. Where images were displaying correctly previously, the terminal now displays the following error Field "image" must not have a selection since type "Boolean" has no subfields.

When an image is added in Wordpress it has a value of null, when no image is added it has a value of false.

I appreciate any help or pointers anybody can give to prevent this happening. Thanks very much in advance!

@craig-doyle-uk craig-doyle-uk changed the title WP ACF repeater with images source_url bug WP ACF repeater with image bug Dec 7, 2017
@craig-doyle-uk
Copy link
Author

I have further narrowed this bug down to being caused when an image is added to the first item of a repeater field. I have found that a hacky way of getting round this bug is to remove the image from the first item in a repeater field and then discard the first item when looping through the data in the front end.

It would be great if this bug could be ironed out relatively soon as we'd like to deploy an e-commerce site we're working on in the coming weeks and the hack-fix is likely to confuse the client.

Appreciate any help that can be given!

@sebastienfi
Copy link
Contributor

Hi @craig-doyle-uk
We are using repeater with image with no problem. Are you returning the Image Object ?
Also if one of your posts doesn't have an image, ACF will give image: false. This is a problem with ACF which is inconsistent in its use of the REST API. To avoid this GraphQL problem, simply define an image for each post.

@craig-doyle-uk
Copy link
Author

Hi @sebastienfi , thanks for the response!
The repeater works on most pages for us, but it breaks on other pages. Our problem is not an error when an image is missing, but when an image is added (and only on the first item in the repeater).
If the image is missing it returns false as expected but if an image is added to the first element in the repeater it returns null for all image fields and causes and GraphQL error.

eg with image added to all elements in an acf repeater :

[
 { 
   image : null
 },
 { 
   image : null
 },
 { 
   image : null
 }
]

With the first image removed :

[
 { 
  image : false
 },
 { 
  image : {
   "id": "40a42e76-47c4-5d7a-bd6b-2decb3b86bdb"  
  }
 },
 { 
  image :  {
   "id": "902a524a-fc52-5e38-a6f2-82f97beda93c"  
  }
 }
]

This bug only occurs intermittently, with everything working well most of the time, but then failing on some pages. In some cases the repeater with Graphql is working perfectly until we add another page and then a page that is working then stops working!

I have no idea of what is happening but I think it is occurring in the normalise.js file in the plugin as I can see the image data is correct when it enters that file.

@jsanchez034
Copy link

I ran into a similar issue when using just an Image field in a simple field group. This is actually an issue with how ACF returns when an image is not set. Checkout the Image field in the ACF repo..
https://github.com/elliotcondon/acf/blob/master/core/fields/image.php#L229
Notice how false is returned if no image is set. The same goes for the Wordpress function wp_get_attachment_url which ACF uses when you define the return value for an Image field as the Image url...
https://github.com/elliotcondon/acf/blob/master/core/fields/image.php#L219
wp_get_attachment_url docs on Wordpress codex...
https://codex.wordpress.org/Function_Reference/wp_get_attachment_url
image
This looks to be a common pattern in Wordpress/PHP. I think the next step forward with this is to add an extra option to the gatsby-source-wordpress plugin so that you can define a map of fields and there types. This way when importing the Wordpress data in normalize.js there default values can be properly set to null or empty string etc. instead of false. Just to be clear this new field map option wouldn't need to define all field types, just Image fields or other fields where there type could be false when not set.

@flmuel
Copy link
Contributor

flmuel commented Dec 22, 2017

I ran into the same issue too I think... I query my post content with flexible contents acf fields, which cause images to return null that are not in the flexible content layout, but I really don't know why :(

@flmuel
Copy link
Contributor

flmuel commented Dec 22, 2017

Well I tried to get more information about where this bug is coming from, but all I found out that in my case only one post get the right value of each acf field.
Example: 5 Posts, each a different image named thumbnail
Output: Only one certain post get the right url
If you add more acf image fields, still only one post will not get null returned...

@jsanchez034
Copy link

I think this is loosely related to this issue around non-existing fields and GraphQL..
#2392
Seems like what could solve this problem is helping Gatsby understand what the schema is for pages, posts ,etc. using the setFieldsOnGraphQLNodeType Gatsby Node API. Check out @jquense's comment on the above issue along with the other comments that follow it..
#2392 (comment)
I think what would be nice is if we could create a "GraphQL schema snaphot" by creating some sample pages, posts, etc. with all ACF fields set, run a command like gatsby generate-schema and then have Gatsby use those "GraphQL schema snaphots" instead of inferring always when gatsby develop or gatsby build is ran.

@craig-doyle-uk
Copy link
Author

I have found two causes for this and a similar bug (elements being added in WP via ACF with FC not available in Gatsby app).

  1. I've found that images that are too large cause the image not to be available (I had an image that was 11mb uploaded, and then cropped/resized using gatsby-transformer-sharp)- when swapped for a smaller original image everything worked as it should.
  2. When some of the ACF options have been left blank or not clicked in the field configuration page. When I was debugging in the WP theme I realised that on some occasions the image was being returned as an object instead of an array as specified. By un-selecting and then re-selecting 'Image Array' in the configuration and then re-saving the pages in question the issue was resolved. This was also causing a bug with select field which I had not selected an option for "Allow Multiple". The data that was displayed in Gatsby was an array containing an integer in some places and a single integer in others. Once again I just made sure that all of the correct options were selected in the configuration page for ACF and re-saved the pages to resolve the issue.

Hope this helps in some cases!

@SimonIMG
Copy link
Contributor

I might have the solution, taken from this issue. I had this exact same issue. Working perfectly before - GraphQL was able to query image IDs and URLs and Gatsby was merrily displaying the image URLs. Then I added another flexible content field which contained an Image upload field (I'd used this flexible content field previously on a different page). I was getting

Field "gallery_image" must not have a selection since type "Boolean" has no subfields

I tried what was suggested by @craig-doyle-uk :- changing the Return Value from Image Array to Image URL and back to Image Array, then resaved the two pages with these fields used.

I also tried the other, earlier suggestion of removing the first item and adding it back in. Still no luck.

I took a look at @jsanchez034 's referenced issue. Still didn't fix my issue.

Finally I looked at @kennethormandy 's reference to #4461 and that had the solution for me.

#4461 (comment)

As per the above post, in my WordPress theme's functions.php file, I added the following...

function nullify_empty($value, $post_id, $field)
{
    if (empty($value)) {
        return null;
    }

    return $value;
}

add_filter('acf/format_value/type=image', 'nullify_empty', 100, 3);

Now my images are querying correctly in GraphQL, Gatsby is running and images in repeatable flexible fields are displaying correctly, while those that don't have them also display correctly.

Hope this helps someone else.

@hussain-t
Copy link

After spending hours on searching a fix for this issue, I came up with my own solution. Add the following function in your functions.php file. This will return an empty string for source_url which is the default property for ACF image in Gatsby GraphQL.

`function set_acf_image_source_url_empty($value, $post_id, $field) {
if ($field['type'] == 'image' && $value === false) {
return (object) ['source_url' => ''];
}

return $value;

}
add_filter('acf/format_value', 'set_acf_image_source_url_empty', 10, 3);
`

I hope this helps :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants