Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass variables between Relay Containers

I'm looking for the good syntax to pass a variable from a parent container to a child container.

Let's say I have theses routes, with a global widget list on / and specific widget lists on /widgets/:WidgetListID.

Note: I use react-router-relay

<Route
    path='/' component={Layout}
  >
    <IndexRoute
      component={WidgetListContainer}
      queries={ViewerQueries}
    />
    <Route
      path='/widgets/:WidgetListID'
      component={WidgetListContainer}
      queries={ViewerQueries}
    />
  </Route>

It's the same <WidgetList/> component, rendered inside <WidgetListContainer/> inside <Layout/> and here is how I try to pass the WidgetListID variable:

Layout.js

class Layout extends React.Component {
  render() {
    return (
      <div>
       ...
        {children}
       ...
      </div>
    );
  }
}

WidgetListContainer.js

class WidgetListContainer extends React.Component {
  render () {
    return (
      <div>
       ...
        <WidgetList 
          viewer={viewer}
        />
      </div>
    )
  }
}

export default Relay.createContainer(WidgetListContainer, {
  initialVariables: {
    WidgetListID: null
  },
  fragments: {
    viewer: ($WidgetListID) => Relay.QL`
      fragment on User {
        ${WidgetList.getFragment('viewer', $WidgetListID)}
      }
    `,
  },
})

WidgetList.js

class WidgetList extends React.Component {
  render () {
    return (
      <div>
        <ul>
          {viewer.widgets.edges.map(edge =>
            <li key={edge.node.id}>{edge.node.widget.name}</li>
          )}
        </ul>
      </div>
    )
  }
}
export default Relay.createContainer(WidgetList, {
  initialVariables: {
    WidgetListID: null
  },
  fragments: {
    viewer: () => Relay.QL`
      fragment on User {
         widgets(first: 10, WidgetListID:$WidgetListID) { 
          edges { 
            node { 
              id, 
              name
            } 
          } 
        } 
      }
    `,
  },
})

I have no problem setting the WidgetListID variable directly inside the WidgetList relay container, it works perfectly fine, but as soon as I try to pass it from the WidgetListContainer relay container I have an empty data object {__dataID__: "VXNlcjo="}. Though, the variable is well printed in my getWidget() function. So something doesn't work at some point but I can't figure out what?

What would be the good syntax to pass the WidgetListID variable from the parent container to the child container?

like image 246
Victorien Avatar asked Nov 10 '22 04:11

Victorien


1 Answers

In the WidgetListContainer, change this:

fragments: {
    viewer: ($WidgetListID) => Relay.QL`
      fragment on User {
        ${WidgetList.getFragment('viewer', $WidgetListID)}
      }
    `,
  },

to

fragments: {
    viewer: ({WidgetListID}) => Relay.QL`
      fragment on User {
        ${WidgetList.getFragment('viewer', {WidgetListID})}
      }
    `,
  },

The first argument to the fragment builder is the Relay variables. So first you need to pull the WidgetListID variable out of the WidgetListContainer's variables, and then you can pass it into WidgetList.getFragment().

Note that the $ symbol is only used inside the Relay.QL template string. Inside the variables object, you refer to the variable by name, without the $.

like image 115
sefnap Avatar answered Jan 04 '23 02:01

sefnap