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 issueHello,
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:
- Created 10 months ago
- Reactions:2
- Comments:5 (3 by maintainers)
Top GitHub Comments
Thanks @M1CK431 - I’ll tag this as a feature request so others in the community can find and weigh in on it 🙏🏻
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:
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 🙏🏼