1
votes

I have a component that shows all users tied to a specific type of entity. The component renders with the apollo graphql compose helper. The export of the component looks like this:

export const UsersContainer = compose(
    connect(mapStateToProps, mapDispatchToProps),
    graphql(gql`
        query manager($id: Int!) {
          manager(id: $id) {
            users {
              id
              firstName
              lastName
              email
              username
            }
          }
        }`, {
    options: (props) => ({
        variables: {
            id: props.currentOrg.org.id
        }
    }),
})
)(Users);

This all works fine. The issue I'm facing is that I want to make this component dynamic so it will work with all entity types (ie. manager, client, vendor). So, in the above query: query manager($id: Int!) would change to: query client($id: Int!), and so forth.

How can I access the redux store to pull in data to dynamically build the gql query? The data is all available in the store. I just need a way to access the props in a way that I can dynamically build the gql query.

1

1 Answers

2
votes

You effectively need to define three different queries and then conditionally switch between them. The problem is the graphql HOC doesn't provide an easy way to derive which query to use from props. This is probably easiest to do with the new Query component, which uses the render props pattern:

const QueryA = gql`query { # blah }`
const QueryB = gql`query { # blah }`

const WrapperComponent = props => {
  const query = props.foo ? QueryA: QueryB
  return (
    <Query query={query}>
      {({loading, error, data}) => (
        <YourComponent/>
      )}
    </Query>
  )
}

const mapStateToProps = ({ foo }) => ({ foo })
export default connect(mapStateToProps)(WrapperComponent)

Using the HOC, you could do something like:

const QueryA = gql`query { # blah }`
const QueryB = gql`query { # blah }`

const QueryAComponent = graphql(QueryA)(YourComponent)
const QueryBComponent = graphql(QueryB)(YourComponent)

const WrapperComponent = props => (
  props.foo
  ? QueryAComponent
  : QueryBComponent
)

const mapStateToProps = ({ foo }) => ({ foo })
export default connect(mapStateToProps)(WrapperComponent)

If you're going the HOC route, you could also use something like recompose's branch to conditionally render the components.