Relay: [compat] Uncaught TypeError: Cannot read property '__classic_node__' of undefined

Created on 14 Jun 2017  Â·  17Comments  Â·  Source: facebook/relay

I keep getting this error every time I try to use createRefetchContainer

import {
  createRefetchContainer,
  graphql,
} from 'react-relay/compat';

and attempt to refetch:

    const refetchVariables = fragmentVariables => ({
      count: fragmentVariables.count + 50,
    });
    this.props.relay.refetch(refetchVariables, null);

image

stack trace:

Uncaught TypeError: Cannot read property '__classic_node__' of undefined
    at getClassicNode (app.js:70847)
    at getClassicOperation (app.js:70865)
    at Object.Container._this._refetch [as refetch] (app.js:109331)
    at AfterSales._loadMore (app.js:123423)
    at onClick (app.js:123488)
    at Object.ReactErrorUtils.invokeGuardedCallback (app.js:67236)
    at executeDispatch (app.js:66763)
    at Object.executeDispatchesInOrder (app.js:66786)
    at executeDispatchesAndRelease (app.js:51349)
    at executeDispatchesAndReleaseTopLevel (app.js:51360)

that's even if I don't pass any queries in the router (I am using import useRelay from 'react-router-relay'; :

  <Route path="after-sales" admin>
    <IndexRoute
      component={AfterSalesPage}
      admin
    />
  </Route>

and just render QueryRenderer in the root component (i.e. AfterSalesPage).

Anything inside AfterSalesPage component is react-relay/compat (none of the react-relay/classic)

@leebyron ?

Most helpful comment

@dilizarov I just resolved my issue today after going back and looking at it. Turns out that I was actually just missing the third argument for createRefetchContainer.

Here is a simplified version of my setup. I have a route config file, like this.

...
const DesignQueries = graphql.experimental`
  query routes_Design_Query($startDate: YearMonthInput, $endDate: YearMonthInput) {
    account {
      ...Design_user @arguments(startDate: $startDate, endDate: $endDate)
    }
  }
`
...
<Route path="/designs" Component={Design} query={DesignQueries} />
...

And the react component with the refetch

...
export default createRefetchContainer(
  Design,
  {
    user: graphql.experimental`
      fragment Design_user on User 
        @argumentDefinitions(
          startDate: { type: "YearMonthInput" },
          endDate: { type: "YearMonthInput" }
        )
      {
        designData(startDate: $startDate, endDate: $endDate) {
           getDesigns
           getTitles
        }
      }
    `
  },
  graphql.experimental`
    query Design_refetch_Query($startDate: YearMonthInput, $endDate: YearMonthInput) {
      user {
        ...Design_user @arguments(startDate: $startDate, endDate: $endDate)
      }
    }
  `,
)

I then call this.props.relay.refetch onClick and update state during ComponentWillReceiveProps

All 17 comments

check if compat is enabled in your .babelrc

@sibelius this is my .babelrc:

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ],
  "env": {
    "development": {
      "plugins": [
        ["relay", {"compat": true, "schema": "./lib/graph/schema.graphql"}],
        "babel-relay-plugin-loader",
        [
          "react-transform",
          {
            "transforms": [
              {
                "transform": "react-transform-catch-errors",
                "imports": [
                  "react",
                  "redbox-react"
                ]
              }
            ]
          }
        ]
      ]
    },
    "production": {
      "plugins": [
        ["relay", {"compat": true, "schema": "./lib/graph/schema.graphql"}],
        "babel-relay-plugin-loader"
      ]
    }
  }
}

can you post your relay environment?

@sibelius its relay classic:

import Relay from 'react-relay/classic';
import useRelay from 'react-router-relay';

ReactDOM.render((
  <Router
    environment={Relay.Store}
    history={browserHistory}
    render={applyRouterMiddleware(useRelay, useScroll(shouldUpdateScroll))}
    routes={routes}
    onUpdate={logPageView}
  />
), document.getElementById('root'));

image

and this is what it looks like before it crashes:

image

Relay environment inside QueryRenderer:

image

Relay environment inside component that is inside QueryRenderer:

image

Another error, I get a lot (related to this issue):

image

the problem happens on this line of code:

var query = getOperation(taggedNode);

and taggedNode in relay/compat app is undefined, whereas in relay modern app:

image

function () {
      return __webpack_require__(497);
    }

It looks like babel-plugin-relay somehow isn't running in compat mode, although I do see that flag in the config you posted. Is it possible that the code is being transformed against a different Babel config?

@josephsavona well I do have this("babel-relay-plugin-loader": "^0.11.0", ): https://www.npmjs.com/package/babel-relay-plugin-loader in my package.json dependencies... along with: "babel-plugin-relay": "^1.0.1", and if I change my webpack module loaders from this:

  module: {
    loaders: [
      { test: /\.sass$/, loader: 'style-loader!css-loader!sass-loader' },
      { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
      { test: /\.json$/, loader: 'json-loader' },
    ],
  },

to this:

  module: {
    loaders: [
      { test: /\.sass$/, loader: 'style-loader!css-loader!sass-loader' },
      { 
        test: /\.js$/, 
        loader: 'babel-loader', 
        exclude: /node_modules/,
        query: {
          plugins: ['relay', {'compat': true, 'schema': './lib/graph/schema.graphql'}],
        },
      },
      { test: /\.json$/, loader: 'json-loader' },

I get this:

ERROR in ./lib/app/app.js
Module build failed: Error: Plugin 1 specified in "base" provided an invalid property of "compat"
    at Plugin.init (/app/node_modules/babel-core/lib/transformation/plugin.js:131:13)
    at Function.normalisePlugin (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:152:12)
    at /app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:184:30
    at Array.map (native)
    at Function.normalisePlugins (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
    at OptionManager.mergeOptions (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
    at OptionManager.init (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
    at File.initOptions (/app/node_modules/babel-core/lib/transformation/file/index.js:212:65)
    at new File (/app/node_modules/babel-core/lib/transformation/file/index.js:135:24)
    at Pipeline.transform (/app/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
    at transpile (/app/node_modules/babel-loader/lib/index.js:48:20)
    at Object.module.exports (/app/node_modules/babel-loader/lib/index.js:163:20)
webpack: Failed to compile.

removing babel-relay-plugin-loader by:

npm uninstall --save babel-relay-plugin-loader

and removing:

        query: {
          plugins: ['relay', {'compat': true, 'schema': './lib/graph/schema.graphql'}],
        },

but still keeping .babelrc removes the Plugin 1 specified in "base" provided an invalid property of "compat" error, but I still get Uncaught TypeError: Cannot read property '__classic_node__' of undefined error

@codepreneur were you able to fix this? I am also getting the Uncaught TypeError: Cannot read property '__classic_node__' of undefined error when I try to use createRefetchContainer and this.props.relay.refetch

I'm sorry this issue has sat here for so long. In an attempt to clean up our issue queue we're closing some aging or unclear-action issues.

This definitely sounds like a build problem. I've filed a note to improve this error message so that it's more clear that this is related to the built artifacts with suggestions on how to fix.

If you have more to share, please feel free to reopen it with an update.

I'm having the same issue

Having a similar issue and may be related. Getting Uncaught (in promise) TypeError: Cannot read property 'modern' of undefined when using createRefetchContainer and this.props.relay.refetch.

.babelrc

{
  "presets": ["es2015", "react", "stage-0"],
  "plugins": [
    ["relay", {"compat": true, "schema": "cached-schema.json"}]
  ]
}

@kbbqiu I have the same exact issue. Can't figure out what is wrong. Did you ever resolve it?

@dilizarov I just resolved my issue today after going back and looking at it. Turns out that I was actually just missing the third argument for createRefetchContainer.

Here is a simplified version of my setup. I have a route config file, like this.

...
const DesignQueries = graphql.experimental`
  query routes_Design_Query($startDate: YearMonthInput, $endDate: YearMonthInput) {
    account {
      ...Design_user @arguments(startDate: $startDate, endDate: $endDate)
    }
  }
`
...
<Route path="/designs" Component={Design} query={DesignQueries} />
...

And the react component with the refetch

...
export default createRefetchContainer(
  Design,
  {
    user: graphql.experimental`
      fragment Design_user on User 
        @argumentDefinitions(
          startDate: { type: "YearMonthInput" },
          endDate: { type: "YearMonthInput" }
        )
      {
        designData(startDate: $startDate, endDate: $endDate) {
           getDesigns
           getTitles
        }
      }
    `
  },
  graphql.experimental`
    query Design_refetch_Query($startDate: YearMonthInput, $endDate: YearMonthInput) {
      user {
        ...Design_user @arguments(startDate: $startDate, endDate: $endDate)
      }
    }
  `,
)

I then call this.props.relay.refetch onClick and update state during ComponentWillReceiveProps

I actually had the same exact issue and fixed it a few days ago. Relay is a
tricky little thing with EXCELLENT documentation ;)

On Mon, Oct 2, 2017 at 9:17 PM Kevin Qiu notifications@github.com wrote:

@dilizarov https://github.com/dilizarov I just resolved my issue today
after going back and looking at it. Turns out that I was actually just
missing the third argument for createRefetchContainer.

Here is a simplified version of my setup. I have a route config file, like
this.

...
const DesignQueries = graphql.experimental query routes_Design_Query($startDate: YearMonthInput, $endDate: YearMonthInput) { account { ...Design_user @arguments(startDate: $startDate, endDate: $endDate) } }
...

...

And the react component with the refetch

...
export default createRefetchContainer(
Design,
{
user: graphql.experimental fragment Design_user on User @argumentDefinitions( startDate: { type: "YearMonthInput" }, endDate: { type: "YearMonthInput" } ) { designData(startDate: $startDate, endDate: $endDate) { getDesigns getTitles } }
},
graphql.experimental query Design_refetch_Query($startDate: YearMonthInput, $endDate: YearMonthInput) { user { ...Design_user @arguments(startDate: $startDate, endDate: $endDate) } } ,
)

I then call this.props.relay.refetch onClick and update state during
ComponentWillReceiveProps

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/facebook/relay/issues/1887#issuecomment-333734305,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADoZ6qnFNuGvkkJRO6_VR7LMvIpi_HYOks5sobVEgaJpZM4N6Fmh
.

>

Sent from my iPhone

I solved with the same approach @kbbqiu

Was this page helpful?
0 / 5 - 0 ratings