Apollo-client: Add support for GraphQL variables default values

Created on 21 Nov 2016  路  10Comments  路  Source: apollographql/apollo-client

good-first-issue 馃檹 help-wanted 馃ウ low-priority

Most helpful comment

One use case I've run into is with directives.

For example, if I want to reuse a query for different components, but they query a different subset of fields:

query user($id: Int, $withGroups: Boolean = false, $withFriends: Boolean = false) {
    user(id: $id) {
      id
      username
      friends @include(if: $withFriends) {
        id
        username
      }
      groups @include(if: $withGroups) {
        id
        name
        messages(limit: 1) {
          ... MessageFragment
        }
      }
    }
  }

Here, it would be nice to default to false for withGroups and withFriends, and only opt-in with variables. It's a small change, but I imagine could get more complicated if you wanted to have optional filters with defaults, etc.

Maybe there's a nicer way to do this?

Also, when running the code with default values, I would receive an error, but the error message wasn't serializable so it didn't make it into reducer, so I needed to create middleware to log it. I'm working on a RN app so no apollo dev tools yet. I don't know if this is a general issue for some subset of errors that could use improving, but wanted to bring it to your attention, and happy to help if so.

All 10 comments

@iki sure, we'll implement it some time. I would give this relatively low priority at the moment though, because I think default values for variables are most useful on the server. On the client, I think it's just as convenient to provide that default value yourself in the component that issues the query. But maybe you have a compelling use-case?

One use case I've run into is with directives.

For example, if I want to reuse a query for different components, but they query a different subset of fields:

query user($id: Int, $withGroups: Boolean = false, $withFriends: Boolean = false) {
    user(id: $id) {
      id
      username
      friends @include(if: $withFriends) {
        id
        username
      }
      groups @include(if: $withGroups) {
        id
        name
        messages(limit: 1) {
          ... MessageFragment
        }
      }
    }
  }

Here, it would be nice to default to false for withGroups and withFriends, and only opt-in with variables. It's a small change, but I imagine could get more complicated if you wanted to have optional filters with defaults, etc.

Maybe there's a nicer way to do this?

Also, when running the code with default values, I would receive an error, but the error message wasn't serializable so it didn't make it into reducer, so I needed to create middleware to log it. I'm working on a RN app so no apollo dev tools yet. I don't know if this is a general issue for some subset of errors that could use improving, but wanted to bring it to your attention, and happy to help if so.

@srtucker22 this is a feature we would be happy to merge if you wanted to implement it 馃槉

looking into it. got my apollo-client contributor env setup. hopefully will have some free time soon to mess with it

@calebmer another common use case is simply whenever it's more appropriate in codebase to setup default query/mutation parameter values in gql, e.h. if they are internal parameters and the user module which attaches given query/mutation to a redux component should not care about those parameters at all.

@srtucker22 I seem to be running into this as well. I pass default variables to the directives in Apollo client, but it seems to still want them when I pass the query through my component. I get the following error:

Uncaught Error: The operation 'academyQuery' wrapping 'branch(CourseListRaw)' is expecting a variable: 'lessonList' but it was not found in the props passed to 'Apollo(branch(CourseListRaw))'

Here is my query:

query academyQuery($lessonList: Boolean = true, $lessonMD: Boolean = true) {
  repository(owner:"loganpowell", name:"Census_Academy") {
    # Census_Academy
    name
    ... on Repository {
      object(expression: "master:Courses"){
        oid
        ... on Tree {
          oid
          entries {
            # API_Introducction
            name
            oid
            ... @include (if: $lessonList) {
              object {
                ... on Tree {
                  oid
                  entries {
                    # e.g., "Introduction to ..."
                    name
                    oid
                    ... @include (if: $lessonMD) {
                      object {
                        ... on Blob {
                          # markdown here
                          text
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

and here is my code:

import React from 'react'
import { graphql } from 'react-apollo'
import { branch, renderComponent, compose } from 'recompose'
import academyQuery from '../../../services/graphql/github/api.graphql'

const Loading = () => (
  <div>Loading</div>
);

const displayLoadingState = branch(
  (props) => props.data.loading,
  renderComponent(Loading),
);

const CourseListRaw = ({ data: { repository } }) => (
  <ul>
    {repository.object.entries.map(course =>
      <li key={course.oid}>
        {course.name}
      </li>
    )}
  </ul>
)

const data = graphql(academyQuery)

const CourseList = compose(
  data,
  displayLoadingState
)(CourseListRaw)

export default CourseList

I apologize for pinging a closed issue, but it was at the top of the google results when I searched for the error. Just figured it might help others who Google the error to post here.

Sorry! Nevermind, my issue was that I was loading data from cache. The default variables work!

@loganpowell how did you fix it? what do you mean loading data from cache? I have the same issue.

@LavaGolem out of the box, Apollo caches query responses, so - when testing/developing - you may have to manually refetch them to refresh the cache.

Has this feature been implemented yet?

Was this page helpful?
0 / 5 - 0 ratings