DEV Community

Discussion on: Use Apollo to Manage the App's Local State

Collapse
 
komyg profile image
Felipe Armoni

Hi,

I am glad that the article was helpful! I do have to update it to Apollo v3, but I haven't had the time yet.

As for your question, I am not sure if you can overwrite a field that comes from your remote schema. Did you try to add the @client annotation on the field? Did that trigger your read function? If not, maybe you can try creating a resolver for this particular field.

We had a problem a little while ago, in which we had an object that did not have an ID field. We wanted to add it in the client so that we could use the readFragment and writeFragment functions from Apollo and optimize our data handling.

We tried to use a read function for this, but it wasn't working, so we had to create a custom resolver for it, even though we are using Apollo 3. I am not sure if this was because the ID field is a special one, since it is used in the cache denormalisation, but it was the recommendation that we received from the Apollo dev team.

Thanks,
Felipe

Collapse
 
1awaleed profile image
1awaleed • Edited

Thanks @felipe for your reply.

Adding @client should when I am using a value as a client local state but this is not what I am trying todo. Using @client works great. I am using the typePolicy read function to read a string field bar and returning either true or false. The functionality is working fine but typescript is complaining 😭 The remote type used here with introspection is string but I want to use it everywhere in the code as boolean. This is called scheme stitching (I think?)

Regarding your problem, I think the problem is with the ID but no worries, In apollo/client v3, Now you can set a function that defines & returns unique keys for specific types without the need for resolvers. You can read more about it here: apollographql.com/docs/react/cachi...

I have a small question regarding how you use readFragment and writeFragment.
does readFragment reads sibling fields of the same type? Another thing is what would happen if you read a field of an instance of an object that was never fetched before? does it crash or throw error or try to fetch that field?

So far, Apollo's experience have been great and I am already seeing a lot of benefits using it.

Thanks
A. Waleed

Thread Thread
 
komyg profile image
Felipe Armoni

Hi @1awaleed ,

Thanks for the tip regarding the ID. I will look into that.

As for your schema stiching problem, if you are using the Graphql Codegen, you could try to extend the remote object using something like this:

extend type Product {
  quantity: Int!
  isValid: Boolean!
}
Enter fullscreen mode Exit fullscreen mode

But I have only used this to add extra fields to an existing type, not to override existing ones. On that subject, is it absolutely necessary to override the remote field? Can't you create a local boolean field that uses the remote one as a reference?

As for the readFragment and writeFragment question: yes, you use them with sibling fields and with any other type that has an ID and a __typename. For example:

{
  "productEdge": {
    "id": "UHJvZHVjdEVkZ2U6MQ==",
    "__typename": "ProductEdge",
    "edges": [
      {
        "node": {
          "id": "UHJvZHVjdDox",
          "__typename": "Product",
          "numericalId": 1,
          "name": "Product 1"
        }
      },
      {
        "node": {
          "id": "UHJvZHVjdDoy",
          "__typename": "Product",
          "numericalId": 2,
          "name": "Product 2"
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

You can read and write the products above like this:

const productFragment = gql`
  fragment product on Product {
    numericalId
    name
  }
`

const product1 = client.readFragment({ fragment: productFragment, id: 'Product:UHJvZHVjdDox' });
const product2 = client.readFragment({ fragment: productFragment, id: 'Product:UHJvZHVjdDoy' });

client.writeFragment({ fragment: productFragment, id: 'Product:UHJvZHVjdDox', data: { ...product2, name: 'new name' } });
Enter fullscreen mode Exit fullscreen mode

So you can read and write to sibling fields using readFragment and writeFragment, but since you have to pass the ID of the object you want, you can only read and write to one at the time.

If you want to change two or more siblings at the same time, I would recommend using either using a query or a fragment that retrieves a higher level element, for example:

const productQuery = gql`
  query ProductQuery {
    productsEdge {
      edges {
        node {
          numericalId
          name
        }
      }
    }
  }
`;

const productsFragment = gql`
  fragment products on ProductEdge {
    edges {
      node {
        numericalId
        name
      }
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

I hope this answers you question.

Thanks,
Felipe

Thread Thread
 
1awaleed profile image
1awaleed

Thanks a lot @ Felipe, you have been helped a lot.