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

bug(gatsby-source-strapi): Cannot read properties of undefined (reading 'split') #383

Open
cschenio opened this issue Mar 2, 2023 · 8 comments
Labels
documentation Improvements or additions to documentation

Comments

@cschenio
Copy link

cschenio commented Mar 2, 2023

Describe the bug

When gatsby build, the error "Cannot read properties of undefined (reading 'split')" is raised. After investigating, I have narrowed down the issue to the following content type schema:

  • User content type (from permission-user plugin) has a one-to-one relationship with the Editor content type.
  • Post content type has a belongs-to relationship with the Editor content type.
  • Editor content type has a richtext field called bio.

The issue arises when the bio field in the User content type's editor relation is in string format, while the plugin expects it to be in richtext object format.

See these source codes, in the setting above it would be equivalent to extraftFiles(undefined, apiURL), then it causes the error.

      if (type === "richtext") {
        const extractedFiles = extractFiles(value.data, apiURL);

Noted that the bio field in the Post content type's editor relation is in the correct richtext object format with the following structure:

{
  data: string,
  medias: Media[],
}

Proof of Concept

I've added several log lines inside the function download-media-files.extractImages().

Part 1

if (value && type) {
  // Start of log code.
  if (attributeName === "bio") {
    console.log("[uid]", uid, "[type]", type, "[value]", value);
  }
  // End of log code.
  if (type === "richtext") {
    ...

Part 2

      if (type === "relation") {
        // Start of log code.
        console.log("<relation>", "[uid]", uid, "[value]", value, "[target]", attribute.target);
        // End of log code.
        await extractImages(value, context, attribute.target);
      }

The log

The log is as follow, omitting unimportant parts.

<relation> [uid] api::post.post [value] {
  bio: {
    data: "**Chia-Sheng** is an experienced engineer with a strong background in .NET related technologies, including C#
 and Azure. He is proficient in React.js and previously worked with Ruby on Rails. While he's not coding, **Chia-Sheng**
 enjoys traveling and playing football.",
    medias: []
  },
} [target] api::editor.editor

[uid] api::editor.editor [type] richtext [value] {
  data: "**Chia-Sheng** is an experienced engineer with a strong background in .NET related technologies, including C#
and Azure. He is proficient in React.js and previously worked with Ruby on Rails. While he's not coding, **Chia-Sheng**
enjoys traveling and playing football.",
  medias: []
}

<relation> [uid] plugin::users-permissions.user [value] {
  bio: "**Chia-Sheng** is an experienced engineer with a strong background in .NET related technologies, including C#
and Azure. He is proficient in React.js and previously worked with Ruby on Rails. While he's not coding, **Chia-Sheng**
enjoys traveling and playing football.",
} [target] api::editor.editor

[uid] api::editor.editor [type] richtext [value] **Chia-Sheng** is an experienced engineer with a strong background in
.NET related technologies, including C# and Azure. He is proficient in React.js and previously worked with Ruby on
Rails. While he's not coding, **Chia-Sheng** enjoys traveling and playing football.

In the log, we see that the value for the api::post.post relationship is an object with a bio property, where the bio property is itself an object with a data property and a medias property. The data property contains a string value with some biographical information about a person.

On the other hand, the value for the plugin::users-permissions.user relationship is a string containing the same biographical information as the data property in the first schema.

System Info

https://github.com/cschenio/blog

Error Log

This is the log for yarn run build --verbose.

 ERROR #11321  API.NODE.EXECUTION

"gatsby-source-strapi" threw an error while running the sourceNodes lifecycle:

Cannot read properties of undefined (reading 'split')



  TypeError: Cannot read properties of undefined (reading 'split')

  - commonmark.js:9623 Object.parse
    [gatsby]/[commonmark]/dist/commonmark.js:9623:27

  - download-media-files.js:22 extractFiles
    [gatsby]/[gatsby-source-strapi]/dist/download-media-files.js:22:25

  - download-media-files.js:135 extractImages
    [gatsby]/[gatsby-source-strapi]/dist/download-media-files.js:135:32

  - download-media-files.js:186 extractImages
    [gatsby]/[gatsby-source-strapi]/dist/download-media-files.js:186:15

  - download-media-files.js:215
    [gatsby]/[gatsby-source-strapi]/dist/download-media-files.js:215:3

  - async Promise.all


not finished source and transform nodes - 4.688s

error Command failed with exit code 1.
@cschenio cschenio added the bug Something isn't working label Mar 2, 2023
@cschenio
Copy link
Author

cschenio commented Mar 2, 2023

Not sure if this should be resolved in the plugin level, or I should tweak my settings in Strapi, or I did something wrong in Gatsby.

@cschenio
Copy link
Author

cschenio commented Mar 2, 2023

Saw @laurenskling helps maintain this plugin. Tag for notify

@laurenskling
Copy link
Contributor

I'm not too familiar with extractFiles. I haven't used it (since I don't really know what to do with the end result..)

So based on your logs, value.data is not consistently a richtext.

If you call the API endpoints yourself, is the data also inconsistent in have data blocks?

@cschenio
Copy link
Author

cschenio commented Mar 2, 2023

I dug in a bit more. It doesn't seem like it's merely the value.data issue. (So I will probably abandon the PR as well)

So, on the Strapi side, the richtext is stored in the markdown format. It's always string. Things look okay in this regard. All the richtext object stuffs happen after gatsby-transformer-remark take place.

Strapi GraphQL Playground

{
  "data": {
    "usersPermissionsUsers": {
      "data": [
        {
          "attributes": {
            "editor": {
              "data": {
                "attributes": {
                  "bio": "**Chia-Sheng** is an experienced engineer with a strong background in .NET related technologies, including C# and Azure. He is proficient in React.js and previously worked with Ruby on Rails. While he's not coding, **Chia-Sheng** enjoys traveling and playing football."
                }
              }
            }
          }
        }
      ]
    }
  }
}

But on the gatsby side, STRAPI_USER does not see editor at all. But all other pairs exist.

  1. Editor has user.
  2. Post has editor.
  3. Editor has posts.

Gatsby GraphQL Playground
image

I assume the issue has something to do with

  1. user permission plugin
  2. one-to-one relation
    or both.

I will switch the one-to-one to other type to have a quick experiment. Other than that, I have no idea how to progress.

@cschenio
Copy link
Author

cschenio commented Mar 2, 2023

Still can't find STRAPI_USER.editor with the setting Editor has many users.

Posting my gatsby-config.js as well to see if I got something wrong.

    {
      resolve: "gatsby-source-strapi",
      options: {
        apiURL: process.env.STRAPI_API_URL,
        accessToken: process.env.STRAPI_TOKEN,
        collectionTypes: ["post", "editor", "user"],
        singleTypes: [],
      },
    },

@laurenskling
Copy link
Contributor

Ah. You are not populating your relations:
https://github.com/gatsby-uc/plugins/tree/main/packages/gatsby-source-strapi#deep-queries-populate

@cschenio
Copy link
Author

cschenio commented Mar 3, 2023

Thanks! I'll give it a try.
BTW, I can't distinguish when I should manually populate the relations, and when it will auto-populate for me. What's the rule of thumb? I would also like to add the guidance into the doc. Now the doc says "how" but didn't mention a lot of "why".

@laurenskling
Copy link
Contributor

I agree the docs aren't giving a lot of examples on doing this. Any help on this would be welcome. Its also hard from Strapi side of things, their docs about populating is also hard to understand. I guess you just need to figure out what works for you.

you should always need to reference your relations. https://docs.strapi.io/dev-docs/api/rest/populate-select#population
* could be enough, but probably not when using Dynamic Zones or components. But you are using normal relations I think, so it could be that a simple

queryParams: {
  populate: '*'
}

is enough.

@moonmeister moonmeister added documentation Improvements or additions to documentation and removed bug Something isn't working labels Mar 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
3 participants