DEV Community

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

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.