denvned/isomorphic-relay

Multiple injectPreparedData issue

jeromecovington opened this issue · 12 comments

I am passing two sets of data to two separate calls to injectPreparedData in one view, like so:

IsomorphicRelay.injectPreparedData(relayInfinite);
IsomorphicRelay.injectPreparedData(relayBreaker);

...yet I am seeing the following error:
image

All works (on server and client) when I only call injectPreparedData once on one set of relay data, like so:

IsomorphicRelay.injectPreparedData(relayInfinite);

I also tried merging both sets of data and calling injectPreparedData once, like so:

IsomorphicRelay.injectPreparedData([...relayInfinite, ...relayBreaker]);

...but then I still get the Uncaught TypeError: dataID.substring is not a function error, as above.

NM, this appears to perhaps be a data issue on my end, as calling only:

IsomorphicRelay.injectPreparedData(relayBreaker);

...reproduces the error, even though it is the only one in the view.

Going to reopen this for now, just in case anybody else has run into a similar issue with prepared data, even though it does seem to be a data issue.

Do you know how can I reproduce the error?

No...I feel like if I knew the difference between the query/result set that works and the one that doesn't, I would better understand the solution, as well! When I run the query related to the data that doesn't work in my graphiql, there is a valid response with no errors...

And prepareData works just fine with this data set, too! Just not working when injecting the data.

Can you share JSON representation of relayBreaker?

Here's an example of data from a graphql response that can be correlated to the TypeError, whereas other data responses can be easily prepared and injected without issue.

{
  "data": {
    "allBreakers": {
      "hero": [
        {
          "breakerType": "Single Story",
          "ctaTitle": null,
          "ctaURL": null,
          "seasonSlug": null,
          "title": null,
          "promotedItem": [
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": null
            }
          ]
        },
        {
          "breakerType": "Four Story",
          "ctaTitle": null,
          "ctaURL": "",
          "seasonSlug": null,
          "title": "Lorem Ipsum",
          "promotedItem": [
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": {
                "slug": "fashion",
                "url": "http://www.example.com"
              }
            },
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": {
                "slug": "beauty",
                "url": "http://www.example.com"
              }
            },
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": {
                "slug": "fashion",
                "url": "http://www.example.com"
              }
            },
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": {
                "slug": "beauty",
                "url": "http://www.example.com"
              }
            }
          ]
        },
        {
          "breakerType": "Runway Season",
          "ctaTitle": null,
          "ctaURL": null,
          "seasonSlug": "spring-2016-couture",
          "title": null,
          "promotedItem": null
        },
        {
          "breakerType": "Runway Season",
          "ctaTitle": null,
          "ctaURL": null,
          "seasonSlug": "pre-fall-2016",
          "title": null,
          "promotedItem": null
        }
      ],
      "feed": [
        {
          "breakerType": "Single Story",
          "ctaTitle": null,
          "ctaURL": null,
          "seasonSlug": null,
          "title": null,
          "promotedItem": [
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": null
            }
          ]
        },
        {
          "breakerType": "Single Story",
          "ctaTitle": null,
          "ctaURL": null,
          "seasonSlug": null,
          "title": null,
          "promotedItem": [
            {
              "title": "Lorem Ipsum",
              "photosTout": {
                "title": "Lorem Ipsum",
                "url": "http://www.example.com"
              },
              "url": "http://www.example.com",
              "cneID": null,
              "channel": null
            }
          ]
        }
      ]
    }
  }
}

I dropped a console log into node_modules/react-relay/lib/GraphQLStoreDataHandler.js like so:

  /**
   * Checks whether the given ID was created on the client, as opposed to an ID
   * that's understood by the server as well.
   */
  isClientID: function isClientID(dataID) {
    console.log('dataID', dataID);
    return dataID.substring(0, 7) === 'client:';
  },

...and I am seeing:

dataID client:5240261271
dataID client:5240261271
dataID client:5240261271
dataID client:5240261272
dataID client:5240261272
dataID client:5240261272
dataID client:5240261273
dataID client:5240261273
dataID client:5240261273
dataID client:5240261274
dataID client:5240261274
dataID client:5240261274
dataID client:5240261274
dataID Object {}

It seems that values represented in the raw graphql result as null end up being converted to {} when they pass through prepareData. If this is the case, some of these values end up being passed to isClientID which is then throwing a TypeError

I didn't have time to investigate the issue yet, but there is a chance it resolved itself in the latest version of isomorphic-relay. Could you try it?

Unfortunately, when taking the update to isomorphic-relay, react-relay and babel-relay-plugin, several things (unrelated to this issue), break. One of which is our custom network layer which issues get rather than post requests to graphql - again unrelated to the specific problem this issue is concerned with, just sharing information.

According to discussion in facebook/relay#848, this is neither an error in isomorphic-relay nor in relay, so I'm closing it.