When I use next query
videoQuiz(slug: $slug) {
id
slug
title
}
I get next response:
{
id: ...
slug: ...
title: ...
__typename: ...
}
I know and understand that apollo-client will add __typename automatically into the query. But my question is if it is all right that I will get it in my response. Currently I am using this object as input for mutation which is defined as
myMutation(input: MyInput): MyPayload
input MyInput {
id
slug
title
}
And therefore I need to remove __typename for each mutation.
I do not want to complain. I am just asking if it is feature or bug.
@seeden it is the intended default behavior. Apollo Client uses __typename
in order to determine a data id when handling cache updates (https://github.com/apollographql/apollo-client/blob/master/src/ApolloClient.ts#L85-L95). It also is helpful to not strip them to the end result for doing optimistic updates based on previous data since __typename
is part of that response data!
I hope this was helpful! If not, please feel free to reopen the issue and we can keep discussing it 馃憤
Sorry for reopening, but it doesn't make sense to me. You can't mutate with __typename
key name otherwise you need to include it inside of your schema on each nested object.
@jbaxleyiii Agreed with @mhlavacka, this field breaks my mutations.
I am having same problem. I am parsing long list of data and at the end i have to test for __typename and remove it manually every time. That is huge waste of time... any solutions to remove this from query ?
You can remove it by adding addTypename: false
in your Apolloclient init:
const client = new ApolloClient({
networkInterface,
addTypename: false
});
@jbaxleyiii It would be useful to know exactly the consequences of turning this off. I can't quite piece it together from the various issues on the topic. I'm assuming turning this off will break caching in some way?
To stop adding __typename
by default in the queries/mutations, addTypename
field must be set to false
in the InMemoryCache
constructor.
const client = new ApolloClient({
link: new HttpLink({uri: MY_URL}),
cache: new InMemoryCache({
addTypename: false
})
});
Does anybody have a script to remove __typename from nested object of Query response?
@Access2emma you can use https://github.com/jonschlinkert/omit-deep like so:
omitDeep(data, '__typename')
I'd recommend against introducing a dependency just to do this:
const omitTypename = (key, value) => (key === '__typename' ? undefined : value)
const newPayload = JSON.parse(JSON.stringify(payload), omitTypename)
As far as setting the addTypename
option in the InMemoryCache
to false, my understanding is that this will negatively affect cache performance, but I haven't dug in deep enough to know the consequences.
Can anyone from the apollo team chime in here, either by explaining the consequences, or linking some documentation? The readme states:
If id and _id are not specified, or if __typename is not specified, InMemoryCache will fall back to the path to the object in the query, such as ROOT_QUERY.allPeople.0 for the first record returned on the allPeople root query.
It's not really clear what the performace impact is here.
If you're using apollo-boost
, then it looks like this...
import ApolloClient from "apollo-boost";
import { InMemoryCache } from 'apollo-cache-inmemory';
export default new ApolloClient({
uri: "http://localhost:8030/graphql",
cache: new InMemoryCache({
addTypename: false
})
});
If you're using graphql
HOC/decorator from react-apollo
and want to avoid having to manually remove __typename from every response, you can just require this module https://www.npmjs.com/package/typename-monkey-patch somewhere near the entry point of your app.
It monkey patches the graphql HOC from react-apollo so that __typename is filtered out before sending data to your wrapped component.
Note that setting addTypename
to false
makes fragments unusable and breaks apollo's cache state normalization.
Just a note on using the JSON.stringify()
solution from @danderson00 - if you want to do file uploads and you use something like apollo-upload-client then the serialization-parse step will destroy your reference to the File
object and the upload will not work.
Combining solutions from a few places (including @danderson00 and this readme):
import { ApolloClient } from 'apollo-client';
import { ApolloLink, from } from 'apollo-link';
import link from './link';
// Strip __typename from variables
const middleWareLink = new ApolloLink((operation, forward) => {
if (operation.variables) {
const omitTypename = (key, value) => (key === '__typename' ? undefined : value);
// eslint-disable-next-line no-param-reassign
operation.variables = JSON.parse(JSON.stringify(operation.variables), omitTypename);
}
return forward(operation);
});
export default new ApolloClient({
link: from([
middleWareLink,
link,
]),
});
in Angular JS
import ApolloClient from "apollo-boost";
import { InMemoryCache } from 'apollo-cache-inmemory';
export default new ApolloClient({
uri: "http://localhost:8030/graphql",
cache: new InMemoryCache({
addTypename: false
})
});
how to do in androdi please help...
It would make sense to have __typename be a Symbol. That way you expose metadata without doing it inband and confusing code which just wants to deal in data.
Setting addTypename: false
does screw up my schema, is it worth it to instead just remove __typename
from data
props as results of <Query>
?
Hi All
In the above thread, I have posted the answer for this problem please refer to it.
Please let me know if it works for you.
Regards
Rigin Oommen
Man, this is a dumb problem to be dealing with.
Man, this is a dumb problem to be dealing with.
Then please suggest the optimal solution.
The reason __typename
is included in response objects is that folks frequently update those objects and write them back into the store, and the cache would behave differently if it could not rely on receiving the same __typename
that it previously saw. Specifically, __typename
information is crucial for computing an ID for the object, so that the cache knows you're referring to the same entity as before, rather than some new, unidentifiable entity.
I have tried multiple times to exclude unwanted __typename
fields from result objects (#5311, #5154), but I have since become convinced that they are necessary: #5320. This position is not likely to change unless someone who fully understands the problem comes up with a better solution than I have been able to find.
Making __typename
non-enumerable is possible, but the mere presence of non-enumerable properties slows down all operations on the object (thanks JavaScript!). Otherwise, I would be happy to hide this behavior just so people would stop complaining.
Specifically,
__typename
information is crucial for computing an ID for the object, so that the cache knows you're referring to the same entity as before, rather than some new, unidentifiable entity.
Perhaps a silly question, but if all id fields in the schema are UUIDs, does that make __typename
unnecessary? Could this property be used somehow?
What about this case: I am trying to set initial data in local cache, sth like this:
client.cache.writeData({
data: {
isLoggedIn: !!window.localStorage.getItem('token'),
cartItems: [],
params: { name: 'test' }
}
})
And I've got warning that __typename
is missing from params and when I add it then warning disappears and I've got correct response. But my question would be: Should I assign value(something unique) by myself? sth like this :
client.cache.writeData({
data: {
isLoggedIn: !!window.localStorage.getItem('token'),
cartItems: [],
params: { name: 'test', __typename: 'params_unique_test' }
}
})
Specifically,
__typename
information is crucial for computing an ID for the object, so that the cache knows you're referring to the same entity as before, rather than some new, unidentifiable entity.Perhaps a silly question, but if all id fields in the schema are UUIDs, does that make
__typename
unnecessary? Could this property be used somehow?
The ID doesn't need to be a uuid. It just needs to be unique to the type of object. You can technically have a user object with ID 1, another with ID 2, and also have a list object with ID 1, another with ID 2.
Specifically,
__typename
information is crucial for computing an ID for the object, so that the cache knows you're referring to the same entity as before, rather than some new, unidentifiable entity.Perhaps a silly question, but if all id fields in the schema are UUIDs, does that make
__typename
unnecessary? Could this property be used somehow?The ID doesn't need to be a uuid. It just needs to be unique to the type of object. You can technically have a user object with ID 1, another with ID 2, and also have a list object with ID 1, another with ID 2.
Yes, the ID doesn't _have_ to be a UUID, but I think what @vlindhol is getting at is _if_ all your ID are UUIDs then maybe we don't need __typename
for the cache to work correctly.
I'd recommend against introducing a dependency just to do this:
const omitTypename = (key, value) => (key === '__typename' ? undefined : value) const newPayload = JSON.parse(JSON.stringify(payload), omitTypename)
As far as setting the
addTypename
option in theInMemoryCache
to false, my understanding is that this will negatively affect cache performance, but I haven't dug in deep enough to know the consequences.Can anyone from the apollo team chime in here, either by explaining the consequences, or linking some documentation? The readme states:
If id and _id are not specified, or if __typename is not specified, InMemoryCache will fall back to the path to the object in the query, such as ROOT_QUERY.allPeople.0 for the first record returned on the allPeople root query.
It's not really clear what the performace impact is here.
The only problem with this approach is that it will break file uploads. Because we need the File
object and when you stringify we will lose information for the upload
Most helpful comment
To stop adding
__typename
by default in the queries/mutations,addTypename
field must be set tofalse
in theInMemoryCache
constructor.