Recursive fetching of a connection is rejected by Relay. Reproducible on the Relay playground

时间:2016-07-11 21:22:50

标签: recursion relayjs

One more try with the same issue as here https://github.com/facebook/relay/issues/1243. But this time I made it reproducible on the Relay playground.

The idea is to fetch data recursively when a user hovers over a parent category.

I've made two gists. One with the schema and the second with the app. Just copy and paste them into the playground, hover over the catName2 and you'll get the error.

The schema https://gist.github.com/GrigoryPtashko/d110b72076a4611657d5364109ba5905.

The app https://gist.github.com/GrigoryPtashko/c27d6421f1f02c78dc054b2874b4ac87.

The problem is when the inner fragment is included and data-fetched the Relay "rejects" the data that comes back from the backend.

When I wrote the first issue, I thought that this is some issue with my graphql backend (it is not in JS). But now I made it reproducible without even the backend.

Seems to me this is none the less a bug.

Thanks.

PS Here's the schema and the app pasted into the relay playgroud

1 个答案:

答案 0 :(得分:1)

The exception you've encountered is Cannot read property 'map' of undefined. This is because the categories prop passed in here is undefined:

<CategoryItemSubcategoryListContainer 
  categories={this.props.category.categories}
  key={this.props.category.id}
/>

The problem is that you've expected a categories prop to materialize on the data supplied to CategoryItem by Relay. Taking a look at the fragment for CategoryItem though…

fragments: {
  category: variables => Relay.QL`
    fragment on Category {
      id
      name
      ${CategoryItemSubcategoryListContainer
        .getFragment('categories')
        .if(variables.expanded)
      }
    }
  `,
},

You can see that categories is nowhere to be found. It's included via CategoryItemSubcategoryListContainer.getFragment(…), for sure, but since CategoryItem has not fetched it explicitly, Relay masks that data out of its props.

The solution is either to:

  1. Pass this.props.category into CategoryItemSubcategoryListContainer
  2. Move the connection call categories(first: …) up to CategoryItem

Here's a link to a working Playground that implements option one: facebook.github.io/relay/prototyping/playground.html#source=...