-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a way to strip __typename field from query and mutation results #6
Comments
Isn't this whats https://www.apollographql.com/docs/react/advanced/fragments.html#filtering-with-fragments |
@smeijer not really. It's the same as addTypename but per query or mutation instead of a global one. |
This is really killing us right now and it'd be a huge help if this functionality was built into apollo |
For anyone using Angular, I am currently using this middleware which strips the '__typename' off all requests. It has come in very handy for me. perhaps someone else would benefit. `
` |
This solution will be failed if you upload file. The file will be converted to object ({}) after use JSON.parse. |
Working with Apollo cache in JS outside of React I ran into this issue. For some reason none of the suggested fixes worked for me. Maybe that's because I have a deeply nested data structure and to accommodate that I use Fragments. In JS, stripping // Deep copy of uiParent
const uiParentCleaned = JSON.parse(JSON.stringify(uiParent))
// Strip __typename from uiParent and item list
delete uiParentCleaned.__typename
uiParentCleaned.items.map((item) => (
// eslint-disable-next-line no-param-reassign
delete item.__typename
)) |
Any updates here? |
Please add this functionality. Super frustrating this is an issue. |
For all the people using the |
We ran into the exact same issue today @matteo-hertel. Out of curiosity, what did you end up doing to get around it? We have a deeply nested structure and it feels very icky to drill into it to avoid stringifying the File. |
I've sticked togheter a function to deeply remove the typename and making sure I'm not touching the File object
and added it as middleware
it worked quite well but I'm not 100% happy with it |
It's frustrating that this feature is still not implemented. It isn't big of a deal for flat structures but if you have nested objects then it's really annoying to have to remove all the |
@lukejagodzinski When working with a |
No argument there. But it would sure be nice to have a simple documented way to eliminate As I recall, I spent a few days wrestling with this issue before I got it settled. |
Removing the __typename shouldn’t be the way to go as it’s important to keep the cache in sync (cache uses the typenames). I am using the ‘omit’ function of lodash to remove the typename from the object before doing an mutation, this works great for us. |
@freshcoat no one talks about removing |
You are able to change what the cache uses for an ID also, instead of '__typename'. |
Why does the mutation care if there are additional fields in |
In most cases @elie222 the '__typename' is not something we include in our inputs, therefore when the mutation is sent to the server along with a '__typename' it doesn't match the shape of our input which is causing issues. When pulling down data from the server it is already on the objects & become redundant to continually remove it. Personally, in my projects, I create an ApolloLink which strips '__typename' out along with undefined values as shown above. |
@RyannGalea I understand the issue. I'm saying that in general, whether the extra field is called |
The middleware solution isn't working for me. Why there is no |
A nice solution would be to make the const obj = { hello: "world" }
const typenameSymbol = Symbol("apolloTypename")
Object.defineProperty(obj, typenameSymbol, { value: "Test" })
console.log(obj)
// --> { hello: 'world' }
console.log(JSON.stringify(obj))
// --> {"hello":"world"}
console.log(obj[typenameSymbol])
// --> Test |
+1 for symbols sounds great 👍 |
In case someone needs stripping only for firing of mutations and not on each query/subscription (in TypeScript): import { GraphQLError, OperationDefinitionNode } from "graphql";
import { getMainDefinition } from "apollo-utilities";
const cleanTypenameLink = new ApolloLink((operation, forward) => {
const omitTypename = (key: any, value: any) =>
key === "__typename" ? undefined : value;
const def = getMainDefinition(operation.query);
if (def && (<OperationDefinitionNode>def).operation === "mutation") {
operation.variables = parse(stringify(operation.variables), omitTypename);
}
return forward ? forward(operation) : null;
}); |
Why is this still not implemented? We need QoL for the development process please |
I run into this issue too. Unluckily the v2.6 client set the object to strict mode. This means it is even not possible to delete __typename "in-place" . A copy of the origin object is required to delete __typename. |
This issue has frustrated me for so long. Even urql has a way to mask typenames easily. Currently, whenever I do mutations, I omit the __typename from the object and spread the rest of the props and this is what I pass into the mutation. It works fine without issue, but it feels a bit manual. I haven't added the addTypename prop to the cache because I'm unsure of the consequences and I already find it very flakey as it is. |
I thought i was doing something wrong doing this manually everytime. I see is old issue. Happy to add my +1 to a symbol solution, or autoremoval on mutation from apolloClient side. |
Please suggest a solution asap. A lot of developers are facing this issue now. |
To be honest, this should be treated as a BUG. Simply because I queried query{A, B} and somehow I get {A, B, __typename} this is an unwanted field. |
Not a bug because is needed even if you're not asking for it. But the fact that we have to manually remove it or apollo does not accept it for mutations seems like a joke. Anyways, this should be the solution: #6 (comment) |
Can we get a response on this query? Why can't the Apollo Client just ignore these additional fields instead of throwing errors? |
The stupid and unscalable work around is: Link seems nice for now, but symbols and the above seem ideal |
In case it helps anybody you can leverage the (not very well known) Will remove deeply nested const cleanPayload = JSON.parse(JSON.stringify(payloadWithTypeName, (name, val) => {
if (name === '__typename') {
delete val[name];
} else {
return val;
}
})); |
Facing this issue too |
Same issue here, but I've (temporarily) solved this with the solution from @MirrorBytes: #6 (comment) Though, I would much prefer to have a native solution to this. |
Same issue, when will you fix it? |
Not exactly a pizza supreme, but it does the trick.... Thought I'd share. ¯\(ツ)/¯ /**
* Iterate through an object until all specified properties have been removed.
*
* @param theObject
* @param removeProperties
* @returns {{}|*}
*/
function unsetProperties(theObject, removeProperties = []) {
if (theObject === null || typeof theObject !== 'object' || removeProperties.length === 0) {
return theObject;
}
const dataObject = {};
Object.keys(theObject).map((key) => {
if (typeof theObject[key] === 'object') {
dataObject[key] = unsetProperties(theObject[key], removeProperties);
}
if (Array.isArray(theObject[key])) {
dataObject[key] = [];
theObject[key].map((item) => {
if (typeof item === 'object') {
dataObject[key].push(unsetProperties(item, removeProperties));
} else {
dataObject[key].push(item);
}
return item;
});
}
if (typeof theObject[key] !== 'object' && !Array.isArray(theObject[key]) && !removeProperties.includes(key)) {
dataObject[key] = theObject[key];
}
return key;
});
return dataObject;
} |
Adding on to to the pile - this is a total pain. |
+1 |
Hey all 👋 This request seems to have had a LOT of attention over the years. Apologies from the maintainers that we've failed to chime in up to this point. There is a lot of history here so I'd like to see if I can restate the ask here to see if I'm understanding this correctly. From what I gather, the issue here seems to be that because Apollo automatically adds the const QUERY = gql`
query Book {
book {
id
title
description
}
}
`
const MUTATION = gql`
mutation UpdateBook(book: Book!) {
book {
id
title
description
}
}
`
const MyComponent = () => {
const { data } = useQuery(QUERY);
const [updateBook] = useMutation(MUTATION);
// ignore the lack of loading/error handling here
const book = data.book;
return (
<button
onClick={() => {
updateBook({
variables: {
book: { ...book, description: 'Updated description' }
}
});
}}
>
Update book
</button>;
);
} Used in this way causes problems because GraphQL inputs don't allow for the use of Does this seem like an accurate reflection of the problem? A bit about the I say this to mention that unless there needs to be a VERY compelling reason to build in the ability to easily strip That being said, if my understanding of the issue as mentioned above is correct, we could consider adding the ability to strip const stripTypename = (value) => {
// ...
}
const stripTypenameLink = new ApolloLink((operation, forward) => {
const variables = stripTypename(operation.variables);
return forward({ ...operation, variables })
}) If anyone would be willing to share more details or anything I've missed, that would be much appreciated. Thanks! |
@jerelmiller Yes, that's right. For me, it's happening because I'm getting objects from a query, modifying them, and then sending them back for an update. __typename is still hanging around, so things are failing. Several people have offered solutions like the pseudocode you pasted above, but there's desire for something official as this seems like a relatively basic feature. |
@livgust awesome, thanks for confirming! This is definitely something I'll chat about with the team to see what makes the most sense. Appreciate it! |
Yes correct!
If it is not possible to change it by a `Symbol.for('typename')` at least
mutations should not throw an error when receiving the `__typename` props
Il mer 22 feb 2023, 6:10 PM Jerel Miller ***@***.***> ha
scritto:
… @livgust <https://github.com/livgust> awesome, thanks for confirming!
This is definitely something I'll chat about with the team to see what
makes the most sense. Appreciate it!
—
Reply to this email directly, view it on GitHub
<#6 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHAYUVCA4RPLII5FUFASBCTWY2FFFANCNFSM4FMRPZSA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
An implementation thought as I've just recently run into this, an added I believe your assessment of the situation above is 100% accurate where people (myself included) are attempting to pass the results of a query as variables to a mutation. To be able to toggle this setting on an individual query would allow for developers to address this on a case-by-case basis instead of at the client/link level. Just my two cents though. Thanks for keeping after this and let me know if I can assist in any way! |
@kyleboe appreciate the input! The biggest problem I have with a setting for the query is that it has downstream effects on caching. Your configured type policies and cache normalization rely on My current thinking is that we transparently just strip I've got this on the docket as an upcoming item I'd like to take a look at. I'll try and keep this updated as progress is made. Thanks again for the feedback! |
Hey all 👋 I sincerely appreciate the patience on this feature! I'm excited to announce that we've merged apollographql/apollo-client#10724 and this feature will be a part of our next minor release This change will be transparent to you as long as you are using
If you have additional feedback or would like to report any bugs related to this feature, please do so by opening an issue in the Thanks! |
Hey all 👋 quick update We found an issue with the new approach. We strip If you have any feedback and would like to chime in on the expected behavior here, please add a comment to apollographql/apollo-client#10767. Thanks! |
Migrated from: apollographql/apollo-client#1564
The text was updated successfully, but these errors were encountered: