lazy-blocks icon indicating copy to clipboard operation
lazy-blocks copied to clipboard

Invalid JSON when querying repeater fields via GraphQL

Open madebyfabian opened this issue 2 years ago • 2 comments
trafficstars

Issue description:

I have created a block with a repeater field. When I query this with WPGraphQL (v1.14.9) and WPGraphQL Content Blocks (v1.1.2) like this:

GraphQL query
query ListPageByUri($uri: ID!) {
  page(id: $uri, idType: URI) {
    id
    title
    uri
    editorBlocks(flat: true) {
      ... on LazyblockHeroSubpage {
        name
        attributes {
          title
          theme
          teasers
        }
      }
    }
  }
}

I do get the following response:

JSON response
  "data": {
    "page": {
      "id": "cG9zdDoyMQ==",
      "title": "Gesundheitswesen",
      "uri": "/gesundheitswesen",
      "editorBlocks": [
        {
          "name": "lazyblock/hero-subpage",
          "attributes": {
            "title": "Gesundheitswesen",
            "theme": "brand",
            "teasers": "%5B%7B%22link%22:%22https://example.com/gesundheitswesen/dienstleistungen%22,%22image%22:%7B%22alt%22:%22%22,%22title%22:%221868_572_21_Life_01%22,%22caption%22:%22%22,%22description%22:%7B%22raw%22:%22%22,%22rendered%22:%22%3Cp%20class=%5C%22attachment%5C%22%3E%3Ca%20href='https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png'%3E%3Cimg%20width=%5C%22278%5C%22%20height=%5C%22300%5C%22%20src=%5C%22https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-278x300.png%5C%22%20class=%5C%22attachment-medium%20size-medium%5C%22%20alt=%5C%22%5C%22%20decoding=%5C%22async%5C%22%20loading=%5C%22lazy%5C%22%20srcset=%5C%22https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-278x300.png%20278w,%20https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-768x829.png%20768w,%20https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png%20823w%5C%22%20sizes=%5C%22(max-width:%20278px)%20100vw,%20278px%5C%22%20/%3E%3C/a%3E%3C/p%3E%5Cn%22%7D,%22id%22:58,%22link%22:%22https://example.com/gesundheitswesen/attachment/1868_572_21_life_01%22,%22url%22:%22https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png%22,%22sizes%22:%22%22%7D,%22description%22:%22Services%22,%22content%22:%22Dienstleistungen%20nach%20Ma%C3%9F%22%7D%5D"
          }
        },
        {},
        {}
      ]
    }
  },
  "extensions": {
    "debug": [
      {
        "type": "DEBUG_LOGS_INACTIVE",
        "message": "GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled."
      }
    ]
  }
}

The issue is that the repeater field is invalid JSON. If you url-decode it, it returns the following:

[{"link":"https://example.com/gesundheitswesen/dienstleistungen","image":{"alt":"","title":"1868_572_21_Life_01","caption":"","description":{"raw":"","rendered":"<p class=\\"attachment\\"><a href='https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png'><img width=\\"278\\" height=\\"300\\" src=\\"https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-278x300.png\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" decoding=\\"async\\" loading=\\"lazy\\" srcset=\\"https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-278x300.png 278w, https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01-768x829.png 768w, https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png 823w\\" sizes=\\"(max-width: 278px) 100vw, 278px\\" /></a></p>\\n"},"id":58,"link":"https://example.com/gesundheitswesen/attachment/1868_572_21_life_01","url":"https://example.com/wp-content/uploads/2023/07/1868_572_21_Life_01.png","sizes":""},"description":"Services","content":"Dienstleistungen nach Maß"}]

Issues

  • there are double quotes inside double quote fields (the html). You cannot parse this without making some wierd regex things to remove the generated html. I don't need the generated html but the whole repeater field is a type String in GraphQL so I cannot un-select it. Bildschirm­foto 2023-07-27 um 09 52 09

Lazy Blocks Version:

3.4.4

WordPress Version:

6.2.2

Any helpful information to reproduce the issue (screenshots, code parts)

The block: Bildschirm­foto 2023-07-27 um 09 54 26

madebyfabian avatar Jul 27 '23 07:07 madebyfabian

For everyone else having this issue, here is a JS/TS method to fix the fields (highly optionated though):

const parseFaultyJSON = <Item>({ faultyJSONString }: { faultyJSONString: string | undefined | null }) => {
  try {
    if (!faultyJSONString) {
      throw new Error()
    }
    
    // The string is orignally URI encoded, so we need to decode it first
    const uriDecoded = decodeURI(faultyJSONString)
    
    // Now remove the `rendered` field because it contains invalid json.
    const cleaned = uriDecoded.replace(/"rendered"[\s\S]*?\\n"/g, '')
    
    // Because the is a `description` object that should be named `image` we need to rename it.
    const removedDuplicateField = cleaned.replace(/"description":{/g, '"image":{')
    
    const removedTailingCommas = removedDuplicateField.replace(/,}/g, '}')
    
    let json = JSON.parse(removedTailingCommas) as Item[]
    return json
  } catch (error) {
    console.error(error)
    return null
  }
}

madebyfabian avatar Jul 27 '23 08:07 madebyfabian

Hi,

Unfortunately, I can't reproduce this issue. I have tested it on a fresh installation without 3rd-party plugins and a standard Twenty Twenty-Three theme.

If you can provide a step-by-step reproduction, it will be helpful. Also, feel free to provide a fix within the Pull Request https://github.com/nk-crew/lazy-blocks/pulls

Regards, Nikita.

nk-o avatar Aug 08 '23 10:08 nk-o