Relay: [relay-compiler] problem with createRefetchContainer

Created on 26 Jun 2017  路  4Comments  路  Source: facebook/relay

Component1.js

import Compoent2 from 'Component2';

class Component1 extends Component {
  render = () => {
    return (
      <div>
          <div>component1</div>
          <Component2 store={this.props.store}></Component2>
      </div>);
  }
}

export default createRefetchContainer(Component1,
  {
    store: graphql.experimental`
      fragment Component1_store on Store
      @argumentDefinitions(arg1: {type: "String", defaultValue: ""})
      {
        field1(arg1: $arg1){
          id
          profile
        }
        ...Component2_store
      }` 
  },
  graphql.experimental`
    query Component1RefetchQuery($arg1: String) {
      store {
        ...Component1_store @arguments(arg1: $arg1)
      }
    }
  `,
);

Component2.js

class Component2 extends Component {
  render = () => {
    return (
      <div>
          <div>component1</div>
          {this.props.store.field1.profile}
      </div>);
  }
}

export default createFragmentContainer(Component2,
  {
    store: graphql.experimental`
      fragment Component2_store on Store
      {
        field1(arg1: $arg1){
          id
          profile
        }
      }` 
  }
);

When relay-compiler, I got

Invariant Violation: RelayFlattenTransform: Expected all fields with the alias `{"directives":[],"field":"field1"}` to have the same name/arguments. Got `field1([{"kind":"Argument","metadata":null,"name":"arg1","value":{"kind":"Literal","value":""},"type":"String"}])` and `field1([{"kind":"Argument","metadata":null,"name":"arg1","value":{"kind":"Variable","variableName":"arg1"},"type":"String"}])`

why and how to solve this problem?

Most helpful comment

It seems that if you fetch the same field with different arguments in different components you need to alias them. E.g. you could change the query in Component2.js to:

class Component2 extends Component {
  render = () => {
    return (
      <div>
          <div>component1</div>
          {this.props.store.component2_field1.profile}
      </div>);
  }
}

export default createFragmentContainer(Component2,
  {
    store: graphql.experimental`
      fragment Component2_store on Store
      {
        component2_field1: field1(arg1: $arg1){
          id
          profile
        }
      }` 
  }
);

All 4 comments

Try adding the @argumentDefinitions(arg1: {type: "String", defaultValue: ""}) to Component2.js as well:

fragment Component2_store on Store
@argumentDefinitions(arg1: {type: "String", defaultValue: ""})
{
  field1(arg1: $arg1){
    id
    profile
  }
}

It seems that if you fetch the same field with different arguments in different components you need to alias them. E.g. you could change the query in Component2.js to:

class Component2 extends Component {
  render = () => {
    return (
      <div>
          <div>component1</div>
          {this.props.store.component2_field1.profile}
      </div>);
  }
}

export default createFragmentContainer(Component2,
  {
    store: graphql.experimental`
      fragment Component2_store on Store
      {
        component2_field1: field1(arg1: $arg1){
          id
          profile
        }
      }` 
  }
);

Sounds like this was solved and not an issue in Relay.

Not a Relay issue but it should be in the docs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jstejada picture jstejada  路  3Comments

sgwilym picture sgwilym  路  4Comments

MartinDawson picture MartinDawson  路  3Comments

fedbalves picture fedbalves  路  3Comments

luongthanhlam picture luongthanhlam  路  3Comments