0

I am having a really hard time trying to get my head around Relay routes, react-router params and building the queries and containers in general!

I want to edit a Feature when the user clicks on a specific Feature in a FeatureList. It passes a param called "id" which is the id of the Feature in Route.js

  <Route path='/' component={AppComponent} queries={ViewerQuery}>
    <IndexRoute component={FeaturesContainer} queries={ViewerQuery} />
    <Route path='/feature' component={FeatureComponent} queries={ViewerQuery} />
    <Route path="/feature/edit/:id" component={FeatureEditComponent} queries={FeatureQuery}/>
    <Redirect from='*' to='/' />
  </Route>

In my FeatureQuery file I have the following query:

export default {
  viewer: (Component) => Relay.QL`
    query {
      viewer {
        ${Component.getFragment('viewer')}
      }
    }
  `
};

At this point I am completely stuck. How do I expand this to include the "id" and query the features using the "id"? And what would the relating relay container fragment be shaped like? I only see examples going one level deep.

I tried this but I know it isn't right:

export default {
    feature: (Component) => Relay.QL`
        query {
            viewer {
                features(id:$id) {
                  ${Component.getFragment('feature')}
                }
            }
        }
    `
};

This is the current relay container that gets a list of the Features, how would this be modified to just return the 1 feature by id? :

export default Relay.createContainer(CreativeEditComponent, {
  fragments: {
    viewer: () => Relay.QL`
        fragment on User {
        id,
        features(first: 20) {
          edges {
            node {
              id
              name
              description

            }
          }
        }
      }`
  }
});

I have tested a query in GraphiQL and it works as expected:

query {
  viewer {
    features(id:"1") {
      edges {
        node {
          id
          name
          description
        } 
      }
    } 
  }
}

Result:

{
  "data": {
    "viewer": {
      "features": {
        "edges": [
          {
            "node": {
              "id": "Q3JlYXRpdmU6MQ==",
              "name": "React",
              "description": "A JavaScript library for building user interfaces."
            }
          }
        ]
      }
    }
  }
}

schema.js:

const userType = new GraphQLObjectType({
  name: 'User',
  description: 'A person who uses our app',
  fields: () => ({
    id: globalIdField('User'),

    features: {
      type: featureConnection,
      description: 'Features that I have',
      //args: connectionArgs,

      args: {
        id: {
          type: GraphQLString,
        },
        after: {
          type: GraphQLString,
        },
        first: {
          type: GraphQLInt,
        },
        before: {
          type: GraphQLString,
        },
        last: {
          type: GraphQLInt,
        },
      },

      resolve: (_, args) => {
        return resolveGetFeatures(args)
      },
    },


  }),
  interfaces: [nodeInterface]
});



const featureType = new GraphQLObjectType({
  name: 'Feature',
  description: 'Feature integrated in our starter kit',
  fields: () => ({
    id: globalIdField('Feature'),
    name: {
      type: GraphQLString,
      description: 'Name of the feature'
    },
    description: {
      type: GraphQLString,
      description: 'Description of the feature'
    }
  }),
  interfaces: [nodeInterface]
});

1 Answer 1

0

You need to pass the router variables to your fragment.

const ViewerQuery = {
  viewer: (Component, vars) => Relay.QL`
    query {
      viewer {
        ${Component.getFragment('viewer', vars)} # <-- this
      }
    }
  `
}

I copied this code detail from here: https://github.com/relay-tools/react-router-relay/issues/92#issuecomment-235641397

Then you can use the id variable in your component, but you need an initial value for id:

export default Relay.createContainer(CreativeEditComponent, {
  initialVariables: {
    id: ''
  },
  fragments: {
    viewer: () => Relay.QL`
        fragment on User {
          id,
          feature(id:$id) {
            id
            name
            description
          }
        }`
    }
});

And in schema.js define a field for your user type, that serves only one feature:

const userType = new GraphQLObjectType({
  name: 'User',
  description: 'A person who uses our app',
  fields: () => ({
    id: globalIdField('User'),
    feature: {
      type: featureType,
      description: 'feature',
      args: {
        id: {
          type: GraphQLString,
          description: 'The id of the feature'
        }
      },
      resolve: (_, args) => resolveGetFeature (args),
    },
    ...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.