简体   繁体   English

缺少对象 GraphQL+Apollo 的选择集错误

[英]Missing selection set for object GraphQL+Apollo error

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:它们在我的 React 代码中的使用方式是使用 Mutation 包装器组件,如下所示:

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:对于我的各种弹出窗口(我有 3 或 4 个不同的弹出窗口,例如menumodal ),打开和关闭它们的更改看起来都一样,只是类型名称和内容不同等。但是,对于对话框,单击时出现此错误在他们:

Network error: Missing selection set for object of type Dialog returned for query field dialog网络错误:缺少为查询字段对话框返回的 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. React 无权访问开发中的实际错误对象。

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.它不能是后端的东西,因为这只是与本地 Apollo 打交道。 I haven't seen this error before and I'm not sure where to go from here.我以前没有见过这个错误,我不知道从哪里开始。

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 :您必须声明一些字段以在dialog内获取,例如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:最初 Apollo 客户端没有验证@client查询/变异的类型,所以你的变异看起来就像你在问题中写的一样:

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:所以关于@Vic 的回答,突变应该更像:

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.通过将dialog字段视为字符串而不是对象来解决此问题。 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;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM