question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add an option in ApolloClient constructor to return a deep copy of query results (or a way to globally transform results after the caching step)

See original GitHub issue

Hello,

With the release of AC2.6 (and it’s the same with AC3), all queries results are now read only. However, there is use cases where it’s handy and intuitive to mutate the query result (which is different than mutate the cache directly).

For example, when using VueJs, dev could write something like this:

export default {
  data: { userMe: null },
  apollo: {
    userMe: { query: userMeQuery }
  }
};

With vue-apollo, userMe query result is stored directly in data.userMe and, in VueJs, data is the dedicated place for mutable data (aka mutate them will trigger a re-render). So dev will intuitively want to mutate the query result, like any other variables in data.

But, because the result object is now read only, for a real world example, when the dev will bind userMe.name to an <input>, a console error will appears saying that name is read only.

Currently, dev have to workaround that on every query this way:

export default {
  data: { userMe: null },
  apollo: {
    userMe: { query: userMeQuery },
    update: ({ userMe }) => JSON.parse(JSON.stringify(userMe)) // <= ugly deep copy
  }
};

To solve that while still preserving the cache from direct mutation, an option deepCopyResults (for example) could be added in ApolloClient constructor.

Another way to solve that could be to add an option transformResults (for example) which accept a function to transform results after they are stored in the cache (a thing that a network link can’t do if I read the documentation correctly). This solution may be more interesting because it allow for any global transformation after the caching step (covering more use cases).

Wdyt? After all, there is already assumeImmutableResults so why not deepCopyResults or transformResults? 🙃

Issue Analytics

  • State:open
  • Created 10 months ago
  • Reactions:2
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
bignimbuscommented, Dec 9, 2022

Thanks @M1CK431 - I’ll tag this as a feature request so others in the community can find and weigh in on it 🙏🏻

0reactions
M1CK431commented, Dec 9, 2022

As you can imagine @bignimbus I have already read carefully vue-apollo documentation (of course, I could still have miss something). The goal of vue-apollo is to integrate AC in VueJs, make a bridge, not to add feature or alter behavior of AC.

As previously said, I’m not the only one concerned and every VueJs developers which use Apollo would have a benefit with this feature request. Example here: https://github.com/vuejs/apollo/issues/58#issuecomment-297988517

Notice that this comment is from Akryum, which is part of VueJs core team and maintainer of vue-apollo library. His advice is:

you need to clone the array

So exactly what I’m requesting here but at a global level.

Also, please notice that in my project I’m often using AC directly in my .js file and I guess I’m not the only one with this mixed usage. Of course, I would like to have a consistent behavior across all my queries regardless if I made them from within a vue component (through vue-apollo) or a regular js file (using AC client directly) and this is possible only if this feature request is made in AC directly.

To conclude, about the “potential performance tax”, most of the time API results are not so giant that JSON.parse(JSON.stringify(data)) have a noticeable impact. In addition, we could imagine a per query optout mecanism, like for fetch policy: a global option + a per query override option and so it become so easy to handle big API results exceptions (if any). Anyway, since it’s an option, people who worry about that could simply not use it 😉

Again, thanks a lot for the time you spent to consider this feature request and provide advises 🙏🏼

Read more comments on GitHub >

github_iconTop Results From Across the Web

Configuring the Apollo Client cache - Apollo GraphQL Docs
The InMemoryCache constructor accepts a variety of configuration options. Configuration options. You can configure the cache's behavior to better suit your ...
Read more >
class ApolloClient - Apollo GraphQL Docs
The ApolloClient constructor ... Provide some optional constructor fields ... The cache that Apollo Client should use to store query results locally.
Read more >
Caching in Apollo Client - Apollo GraphQL Docs
Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache. This enables Apollo Client to respond almost immediately ......
Read more >
Mutations in Apollo Client - Apollo GraphQL Docs
If your mutation returns all of the objects and fields that it modified, you can update your cache directly without making any followup...
Read more >
Customizing the behavior of cached fields - Apollo GraphQL
You can customize how a particular field in your Apollo Client cache is read and written. To do so, you define a field...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found