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

__typename in query response #1913

Closed
seeden opened this Issue Jul 17, 2017 · 16 comments

Comments

Projects
None yet
@seeden
Contributor

seeden commented Jul 17, 2017

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.

@jbaxleyiii

This comment has been minimized.

Member

jbaxleyiii commented Jul 17, 2017

@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 👍

@jbaxleyiii jbaxleyiii closed this Jul 17, 2017

@matthlavacka

This comment has been minimized.

matthlavacka commented Aug 15, 2017

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.

@jjant

This comment has been minimized.

jjant commented Sep 25, 2017

@jbaxleyiii Agreed with @mhlavacka, this field breaks my mutations.

@Dishant15

This comment has been minimized.

Dishant15 commented Oct 13, 2017

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 ?

@matthlavacka

This comment has been minimized.

matthlavacka commented Oct 13, 2017

You can remove it by adding addTypename: false in your Apolloclient init:

const client = new ApolloClient({
  networkInterface,
  addTypename: false
});
@danderson00

This comment has been minimized.

danderson00 commented Nov 30, 2017

@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?

@wawhal

This comment has been minimized.

wawhal commented Mar 21, 2018

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
  })
});
@Access2emma

This comment has been minimized.

Access2emma commented May 1, 2018

Does anybody have a script to remove __typename from nested object of Query response?

@capaj

This comment has been minimized.

capaj commented May 31, 2018

@Access2emma you can use https://github.com/jonschlinkert/omit-deep like so:

omitDeep(data, '__typename')
@danderson00

This comment has been minimized.

danderson00 commented Jun 1, 2018

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.

@mnpenner

This comment has been minimized.

mnpenner commented Jul 20, 2018

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
    })
});
@ikatun

This comment has been minimized.

ikatun commented Jul 28, 2018

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.

@michaelbromley

This comment has been minimized.

michaelbromley commented Sep 13, 2018

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.

@arist0tl3

This comment has been minimized.

arist0tl3 commented Sep 28, 2018

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,
  ]),
});
@Nitishreddy787

This comment has been minimized.

Nitishreddy787 commented Oct 3, 2018

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...

@tahoemph

This comment has been minimized.

tahoemph commented Nov 21, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment