score:2

I've also been experimenting with local state management in apollo, so the following is somewhat contrived and very obscure, but it works.

Putting it bluntly — everything that's not a scalar or on array needs to have a type.

So this:

const defaults = {
  ui: {
    __typename: 'UI',
    states: {},
    values: {}
  }
};

Needs to become, for example, this:

const defaults = {
  ui: {
    __typename: 'UI',
    states: {
      __typename: 'UIStates'
    },
    values: {
      __typename: 'UIValues'
    }
  }
};

And in your query MUST reference a scalar or an array, so naturally your query won't work:

const QUERY = gql`
  {
    ui @client {
      states
      values
    }
  }
`;

You need to go deeper and target the scalars or arrays:

const QUERY = gql`
  {
    ui @client {
      states {
        foo
      }
      values {
        bar
      }
    }
  }
`;

The rest depends on your data.

If you need to filter a query — your query would look something like this (the first one returns all items, the next one filters an item by an id):

const TEST_CLIENT_FILTER_QUERY = gql`
  {
    bzz @client {
      id
      title
    }
    bzz(id: $id) @client {
      id
      title
    }
  }
`

And you will need a resolver for that too. This one is very dirty, I'm not sure it's the apollo-graphql way, but it works for my purposes for now.

    resolvers: {
      Query: {
        bzz: (root, variables, context) => {
          const key = context.getCacheKey({ __typename: 'bzz', id: variables.id })
          return context.cache.extract()[key]
        },
      },
    },

These are my defaults for such a query:

  cache.writeData({
    data: {
      bzz: [
        {
          __typename: 'bzz',
          id: 1,
          title: 'bzz 1',
        },
        {
          __typename: 'bzz',
          id: 2,
          title: 'bzz 2',
        },
      ],
    },
  })

Related Query