admin管理员组

文章数量:1202577

I have a set of mutations that trigger the local state of certain types of popups. They're generally set up like this:

  openDialog: (_, variables, { cache }) => {
    const data = {
      popups: {
        ...popups,
        dialog: {
          id: 'dialog',
          __typename: 'Dialog',
          type: variables.type
        }
      }
    };

    cache.writeData({
      data: data
    });
    return null;
  }

And the defaults I pass in look like:

const defaults = {
  popups: {
    __typename: TYPENAMES.POPUPS,
    id,
    message: null,
    modal: null,
    menu: null,
    dialog: null
  }
};

The way they're used in my React code is with a Mutation wrapper component, like so:

const OPEN_ALERT_FORM = gql`
  mutation AlertOpenDialog($type: String!) {
    openDialog(type: $type) @client
  }
`;

class Alert extends Component {
  render() {
    return (
      <Mutation mutation={OPEN_ALERT_FORM} variables={{ type: ALERT_FORM }}>
        {openDialog => {
          return (
            <Button
              classes="alert-button"
              onClick={openDialog}
              label="Trigger Alert"
            />
          );
        }}
      </Mutation>
    );
  }
}

For my various popups (I have 3 or 4 different ones, like menu and modal), the mutations to open and close them all look the same, just different typenames and content etc. But, for Dialogs, I get this error when I click on them:

Network error: Missing selection set for object of type Dialog returned for query field dialog

...and then the triggering component disappears from the page. Plus, once that happens, all other popup types disappear when you try clicking on them, and either re-throw that error, or say:

Uncaught Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.

I've tried re-writing dialogs to match up with other popup types, and re-writing the components as well, but I'm still getting this error. It does appear to be dialog+Apollo specific. What could be the root of this issue? It can't be a backend thing, because this is only dealing with local Apollo. I haven't seen this error before and I'm not sure where to go from here.

I have a set of mutations that trigger the local state of certain types of popups. They're generally set up like this:

  openDialog: (_, variables, { cache }) => {
    const data = {
      popups: {
        ...popups,
        dialog: {
          id: 'dialog',
          __typename: 'Dialog',
          type: variables.type
        }
      }
    };

    cache.writeData({
      data: data
    });
    return null;
  }

And the defaults I pass in look like:

const defaults = {
  popups: {
    __typename: TYPENAMES.POPUPS,
    id,
    message: null,
    modal: null,
    menu: null,
    dialog: null
  }
};

The way they're used in my React code is with a Mutation wrapper component, like so:

const OPEN_ALERT_FORM = gql`
  mutation AlertOpenDialog($type: String!) {
    openDialog(type: $type) @client
  }
`;

class Alert extends Component {
  render() {
    return (
      <Mutation mutation={OPEN_ALERT_FORM} variables={{ type: ALERT_FORM }}>
        {openDialog => {
          return (
            <Button
              classes="alert-button"
              onClick={openDialog}
              label="Trigger Alert"
            />
          );
        }}
      </Mutation>
    );
  }
}

For my various popups (I have 3 or 4 different ones, like menu and modal), the mutations to open and close them all look the same, just different typenames and content etc. But, for Dialogs, I get this error when I click on them:

Network error: Missing selection set for object of type Dialog returned for query field dialog

...and then the triggering component disappears from the page. Plus, once that happens, all other popup types disappear when you try clicking on them, and either re-throw that error, or say:

Uncaught Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.

I've tried re-writing dialogs to match up with other popup types, and re-writing the components as well, but I'm still getting this error. It does appear to be dialog+Apollo specific. What could be the root of this issue? It can't be a backend thing, because this is only dealing with local Apollo. I haven't seen this error before and I'm not sure where to go from here.

Share Improve this question edited Nov 8, 2018 at 20:56 Cassidy asked Nov 8, 2018 at 20:40 CassidyCassidy 3,4085 gold badges41 silver badges80 bronze badges 6
  • What does the defaults object you pass to withClientState look like? – Daniel Rearden Commented Nov 8, 2018 at 20:51
  • @DanielRearden just updated question with the defaults! – Cassidy Commented Nov 8, 2018 at 20:56
  • Hmm. It looks like that error gets thrown whenever the cache has some object (as opposed to just a scalar value) and you try to read that object from the cache without specifying a selection set (i.e. which fields on the type). You can take a look at the test here. Do you have a query that requests the dialog field on popups without specifying the fields on dialog? – Daniel Rearden Commented Nov 8, 2018 at 21:26
  • i.e. something like query { popups { dialog } } ? – Daniel Rearden Commented Nov 8, 2018 at 21:27
  • @DanielRearden I'll check that out, thanks! I do have a query that checks that, and it appears to be working correctly. – Cassidy Commented Nov 8, 2018 at 22:36
 |  Show 1 more comment

3 Answers 3

Reset to default 15

Solution is to add fields to the query (vs. declaring the top-level object you want to fetch without specifying the fields to fetch). If you have something like:

{
  popups @client {
    id
    dialog
  }
}

you must declare some fields to fetch inside dialog, for example id:

{
  popups @client {
    id
    dialog {
      id
    }
  }
}

Answer to the actual problem seems lay in the query. Initially Apollo client was not validating types for @client queries/mutations so your mutation could look like you wrote it in the question:

mutation AlertOpenDialog($type: String!) {
  openDialog(type: $type) @client
}

the correct way of writing above is to specify (select) all the simple type (scalar) fields you wanna get in a response. So in regard to the @Vic answer the mutation should look more like:

mutation AlertOpenDialog($type: String!) {
  openDialog(type: $type) @client {
    dialog {
      id
    }
  }
}

The fix for this turned out to work by treating the dialog field as a string instead of an object. Changing the function to this did the trick and made the errors go away:

  openDialog: (_, variables, { cache }) => {
    const data = {
      popups: {
        ...popups,
        dialog: variables.type
      }
    };

    cache.writeData({
      data: data
    });
    return null;
  }

本文标签: javascriptMissing selection set for object GraphQLApollo errorStack Overflow