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

Missing images when using relation widget in file collection #2786

Closed
rus-yurchenko opened this issue Oct 23, 2019 · 14 comments
Closed

Missing images when using relation widget in file collection #2786

rus-yurchenko opened this issue Oct 23, 2019 · 14 comments
Assignees

Comments

@rus-yurchenko
Copy link

rus-yurchenko commented Oct 23, 2019

Describe the bug
Brief: When I'm referencing a collection using relation widget(not a file collection, just basic folder collection) I'm getting all data from this relation except images. It just returns null for image field.

More info:
I have case-studies collection and referencing to it through relation widget from both folder and file collections. To access the relation entry I made a node field where I check for the relation string and pass its data to the node. (code below)

In case of relation folder-collection entry -> folder collection all work as expected and I'm getting all 'case-study' data with images.

But in case of relation file-collection entry -> folder collection I'm getting only data from 'case-study' with missed images.

To Reproduce
https://github.com/rusyurchenko/gatsby-netlify-issue

Expected behavior
A relation like 'file-collection entry -> folder collection reference" should return data with resolved images.

**Screenshots / Examples **
Example of file-collection entry -> folder collection reference query.
https://gist.github.com/rusyurchenko/1b58c0df547b30069dd155a1dd25c5c5

Example of relation folder-collection entry -> folder collection
https://gist.github.com/rusyurchenko/289ba43d909355c86cf01c883b860dcf

Applicable Versions:

  • Netlify CMS version: 2.9.7
  • Git provider: BitBucket
  • OS: MacOS Catalina
  • Browser version Chrome 77
  • Node.JS version: 10.16.3

CMS configuration
case-study as the base. marketing' folder collection and loyalty-why-do-need are referenced to the base.
https://gist.github.com/rusyurchenko/cacaaa5fb679e0d79584e514e481e300

onCreateNode: (where queries for collection reference)
https://gist.github.com/rusyurchenko/cff8e95407c7df0b11ca89372313a2e9

gatsby-config.js
https://gist.github.com/rusyurchenko/79396d92bb9340039413787c1ad2452f

Additional context
I think this issue happens because of some issue with image path resolve in file collection.

@erezrokah erezrokah self-assigned this Oct 23, 2019
@erezrokah
Copy link
Contributor

@rusyurchenko Thank you for opening this issue. Do you mind posting a reproduction scenario? (an example repo would be perfect). It will make it easier to pinpoint the exact location of the problem.

@rus-yurchenko
Copy link
Author

@erezrokah Will try to reproduce this issue with default starter later today, thank you!

@rus-yurchenko
Copy link
Author

@erezrokah Hey, sorry for the delay. I've reproduced this issue on the default blog starter. Example repo: https://github.com/rusyurchenko/gatsby-netlify-issue. Attached query example into readme.

@erezrokah
Copy link
Contributor

Thanks @rusyurchenko I'll try to reproduce with the repo and update here

@erezrokah
Copy link
Contributor

erezrokah commented Nov 3, 2019

Related issues:
gatsbyjs/gatsby#4123
gatsbyjs/gatsby#13322
gatsbyjs/gatsby#13938
gatsbyjs/gatsby#14018

From what I managed to figure out from the Gatsby issues, this happens when Gatsby fails to treat the image as a File (and treats it as a string instead).

I managed to work around the issue by flattening the directory structure for the file collection (https://github.com/rusyurchenko/gatsby-netlify-issue/pull/1).

@rus-yurchenko
Copy link
Author

@erezrokah Yeah, it works but the issue is still open. In our case, Gatsby exactly treats the image file as a File since we're not getting an error such as "image" must not have a selection since type "String" has no subfields. We just got null under resolved image file.

@erezrokah
Copy link
Contributor

Hey @rusyurchenko, sorry I forgot to mention it. I was getting "previewImage" must not have a selection since type "String" has no subfields when running yarn develop.
The strange thing is that it didn't happen all the time, and sometimes the error lead to the site not loading at all.

  • Failure image (when I get this error the site doesn't load at all):
    image

  • Success image (the site loads but with a null image):
    image

Both images are from running gatsby clean then gatsby develop on the same code which is very strange and hints to a race condition somewhere.

We'll need to take a closer look at Gatsby code to understand the issue better

@rus-yurchenko
Copy link
Author

@erezrokah Exactly! I'm getting the same issue with a broken image resolving time-to-time. But it's another issue related to gatsby build etc.

@erezrokah
Copy link
Contributor

It still looks like a Gatsby build issue though (maybe not exactly the same one), since the workaround was just to change the folder structure (nothing related to the CMS).

I'll try to look at the Gatsby code to get a better sense of where the frontmatter previewImage field is evaluated. There must be a place there that changes the image string to an object with a publicURL field

@erezrokah
Copy link
Contributor

erezrokah commented Nov 13, 2019

Sorry for the delay, but I think I figured it out.
Gatsby evaluate files relative to their parent node.
This is done here: https://github.com/gatsbyjs/gatsby/blob/44f4ec0970545b6633fd90bf25274ed4980729f0/packages/gatsby/src/schema/resolvers.js#L202

In your code you're putting the path to the relation image under the post node. Specifically for the content/pages/test-page/index.md the relation image path is evaluated relatively to that file, while actually it should be evaluated related content/relations.
My original workaround just moved the post one directory up so it caused the evaluation to succeed.

Another issue is that Gatsby uses an internal map (weak map actually) to map root nodes to specific objects of those nodes. This happens here:
https://github.com/gatsbyjs/gatsby/blob/44f4ec0970545b6633fd90bf25274ed4980729f0/packages/gatsby/src/schema/node-model.js#L357

And here:
https://github.com/gatsbyjs/gatsby/blob/44f4ec0970545b6633fd90bf25274ed4980729f0/packages/gatsby/src/schema/node-model.js#L718

Since you linked the exact frontmatter instance the map (which uses reference equality) returned the wrong root node for the relation frontmatter thus again evaluating the path based on the wrong parent node.

This is evident by running these queries:

query OneNode {
  a: markdownRemark(fields: {slug: {eq: "/relations/test-collection/"}}) {
    id
    excerpt
    fields {
      slug
    }
    html
    frontmatter {
      title
      relation
      previewImage {
        publicURL
      }
    }
  }
}
query TwoNodes {
  a: markdownRemark(fields: {slug: {eq: "/relations/test-collection/"}}) {
    id
    excerpt
    fields {
      slug
    }
    html
    frontmatter {
      title
      relation
      previewImage {
        publicURL
      }
    }
  }
  b: markdownRemark(fields: {slug: {eq: "/pages/test-page/"}}) {
    id
    excerpt
    fields {
      slug
    }
    html
    frontmatter {
      title
      relation
      previewImage {
        publicURL
      }
    }
  }
}

The first one always returns a non null previewImage.
The second one inconsistently returns null for the relation previewImage. Inconsistently due to the usage of a weak map and the fact there is no specific order items are inserted into the map.

The solution was to deep clone the relation frontmatter object and also fix the previewImage when creating the node field: https://github.com/rusyurchenko/gatsby-netlify-issue/pull/2

@rusyurchenko do you mind testing my PR locally?

@rus-yurchenko
Copy link
Author

@erezrokah That works, make sense, thank you! Great explanation and clear solution. It can be closed.

However, it looks like a pretty simple solution and at the same time as some hack.

While solving this problem as a workaround I'm adding a node frontmatter relation value data to the page context and query exact relation object from the following page. Probably do you know another way to do the same (map relation node data to the post node) without doing extra work in onCreateNode?

@erezrokah
Copy link
Contributor

I agree, it does feel like a hack.
Haven't tested it, but I would look into running two queries - one to get the relation field, then using that value to get the relation previewImage.

Closing for now.
Please re-open if you have more questions

@mouhsnimohamed
Copy link

I have the same issue!
in my case I have a non requered image, when i try to query it I got the same error
I tried to to add default value it did not worked


here is my code

about.md
image: ''

aboute.js
frontmatter { image { publicURL } }

config.yml
{ label: Image, name: image, widget: image, required: false, default: '/img/default.png', },

@erezrokah
Copy link
Contributor

Hi @mouhsnimohamed I think https://www.gatsbyjs.org/docs/schema-customization/ is the recommended way to go in your case.

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

No branches or pull requests

3 participants