2

Here's what I'm trying to accomplish: I have a graphql API endpoint that returns me a Project object like this(unrelated fields removed):

{
  "data": {
    "Project": {
      "id": "cjp4b84wkochq0167gpu8oa7h",
      "requests": [
        {
          "id": "cjpbb6jcdpwj00167y4acl5a1",
          "__typename": "Request"
        },
        {
          "id": "cjpbbhlaxpwlx01675jzfyb0j",
          "__typename": "Request"
        },
        {
          "id": "cjpbbifg7pwmg0167s0ob1bm6",
          "__typename": "Request"
        },
      ],
      "__typename": "Project"
    }
  }
}

I want to use apollo-link-state to add a client-side field to all of these Request objects like this:

{
  "data": {
    "Project": {
      "id": "cjp4b84wkochq0167gpu8oa7h",
      "requests": [
        {
          "id": "cjpbb6jcdpwj00167y4acl5a1",
          "expanded": false,
          "__typename": "Request"
        },
        {
          "id": "cjpbbhlaxpwlx01675jzfyb0j",
          "expanded": false,
          "__typename": "Request"
        },
        {
          "id": "cjpbbifg7pwmg0167s0ob1bm6",
          "expanded": false,
          "__typename": "Request"
        },
      ],
      "__typename": "Project"
    }
  }
}

This would allow me to remove local state from my Component that renders these requests. The problem is that when I define defaults for my ApolloClient clientState as follows:

const client = new ApolloClient({
  clientState: {
    defaults: {
      Project: {
        __typename: 'Project',
        requests: [{ __typename: 'Request', expanded: false }],
      },
    },
  },
});

Apollo adds it as a new Project object instead of adding it to the existing one(which has an id):

ROOT_QUERY
  Project: Project
    requests: [Request]
      0:
        expanded: false
  Project({"id":"cjp4b84wkochq0167gpu8oa7h"}): Project
    ▾Project:cjp4b84wkochq0167gpu8oa7h

when I give it the id it adds the "hi" field to the correct project but the requests are still missing the expanded field. And giving the id only works for a specific project obviously.

const client = new ApolloClient({
  clientState: {
    defaults: {
      'Project({"id":"cjp4b84wkochq0167gpu8oa7h"})': {
        __typename: 'Project',
        hi: true,
        requests: [{ __typename: 'Request', expanded: false }],
      },
    },
  },
});

ROOT_QUERY
  Project({"id":"cjp4b84wkochq0167gpu8oa7h"}): Project
    ▾Project:cjp4b84wkochq0167gpu8oa7h
      hi: true
      requests: [Request]
        0:▾Request:cjpbb6jcdpwj00167y4acl5a1
          ...unrelated fields
        1:▾Request:cjpbbhlaxpwlx01675jzfyb0j
        2:▾Request:cjpbbifg7pwmg0167s0ob1bm6

I also tried using the typeDefs field on the clientState object like this:

typeDefs: [`
  schema {
    query: RootQuery
  }

  type RootQuery {
    Project($id: ID): Project
  }

  type Project {
    id: ID!
    requests: [Request]
  }

  type Request {
    id: ID!
    expanded: Boolean
  }
`],

but this doesn't seem to change anything on the cache and I don't know if I can even give it a default value like this.

Maybe I'm misunderstanding how apollo-link-state works (or even how graphql works) any answer to point me in the right direction is appreciated. I'm very much a beginner when it comes to graphql or apollo.

Yunus Gulcu
  • 92
  • 10

1 Answers1

2

You need to provide a client side resolver to your clientState configuration.

const clientState = {
  resolvers: {
    Project {
      expanded: () => false
    }
  }
}

And then you'd pass this into your ApolloClient like so

const apolloClient = new ApolloClient({ clientState });
frix
  • 165
  • 7
  • This worked for setting it to false permanently but how do I mutate it now? I changed "Project" to "Request:" btw. – Yunus Gulcu Dec 20 '18 at 13:09
  • You'll need to set up resolvers for your client side mutations as well. Can you write out the mutation you are trying to apply? – frix Dec 21 '18 at 05:52
  • I tried out the mutation and it actually worked to mutate the cache. I guess this resolver is only called for the first time? I thought it wouldn't let me mutate expanded. – Yunus Gulcu Dec 21 '18 at 14:14
  • @YunusGulcu And frix From where I can configure the project for react with pwa and apollo-link-state. Can you please guide to some link from I can setup the whole project. – Ashh Jan 04 '19 at 13:35
  • @AnthonyWinzlet just start with create-react-app and add Apollo boost. Easiest way to get started – Yunus Gulcu Jan 05 '19 at 00:54
  • Thank you @YunusGulcu **+1**. Can you please give me some link so that I can refer. – Ashh Jan 05 '19 at 05:28
  • 1
    @AnthonyWinzlet start with this [CRA](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app) and then follow this [Apollo-boost](https://www.apollographql.com/docs/react/essentials/get-started.html#installation) – Yunus Gulcu Jan 05 '19 at 14:05