【问题标题】:After GraphQL Query: Property 'then' does not exist on type 'void'在 GraphQL 查询之后:“void”类型上不存在属性“then”
【发布时间】:2020-08-08 07:40:16
【问题描述】:

我正在使用这样的 graphql 突变,并且 .then 和 .catch 完美地工作:

  let submitForm = (
    email: string,
    firstName: string
  ) => {
    setIsSubmitted(true);

    if (email && (firstName)) {
      const input: UpdateUserInput = {};
      if (firstName) {
        input.firstName = firstName;
      }
      updateUser({
        variables: {
          email: email,
          input: input,
        },
      })
        .then(({ data }: ExecutionResult<UpdateUserResponse>) => {
          if (data !== null && data !== undefined) {
            setIsUpdated(true);
          }
        })
        .catch((error: { message: string }) => {
          console.log('Error msg:' + error.message);
        });
    }
  };

现在我在这里为 graphql 查询做类似的事情(下面是更完整的工作版本):

let ShowUsers = () => {
    const where: WhereInput = {};
    if (criteria === '2') {
      if (searchItem) {
        where.firstName_contains = searchItem;
        loadUsers({
          variables: {
            where: where
          },
        })
        .then(({ data }: any) => {
          if (data !== null && data !== undefined) {
          }
        })
      }
    }
}

但我一直收到错误消息Property 'then' does not exist on type 'void'

编辑:

没有 .then、.catch,我的代码可以正常工作。完整的形式是这样的:

function UserSearchPage() {
  const [criteria, setCriteria] = useState('');
  const [searchItem, setSearchItem] = useState('');

  const [loadUsers, { loading, data }] = useLazyQuery(LoadUsersQuery);

  function PrintUsers({ data }: any) {
    return (
      <div>
        {data &&
          data.users.nodes &&
          data.users.nodes.map((c: any, i: any) => (
            <li key={i}>
              Id: {c.id}, First Name: {c.firstName}, Last Name: {c.lastName},
              Email: {c.email}, phoneNumber: {c.phoneNumber}
            </li>
          ))}
      </div>
    );
  }

  let ShowUsers = () => {
    const where: WhereInput = {};
    if (criteria === '1') {
      loadUsers({
        variables: {
          where: where
        },
      });      
    }

    if (criteria === '2') {
      if (searchItem) {
        where.firstName_contains = searchItem;
        loadUsers({
          variables: {
            where: where
          },
        });
      }
    }
  };
  return (
.....);
}

这是 GraphQL 查询本身的样子:

interface UserFilter {
  email_contains: String;
  firstName_contains?: String;
  lastName_contains?: String;
  phoneNumber_contains?: String;
  id?: Number;
}
export const LoadUsersQuery = gql`
  query usersList($where: UserFilter) {
    users(where: $where) {
      nodes {
        id
        email
      }
      totalCount
    }
  }
`;

我还能如何访问数据属性/错误? 从console.log,我知道这是返回的:

Object

__typename: "User"

email: "first@first.com"

firstName: "First"

id: 148

lastName: "User"

phoneNumber: "+49123"

但是如果我尝试访问让我们说data.users.id,为什么我会得到未定义?我该如何解决这个问题?

【问题讨论】:

  • loadUsers在哪里?
  • 问题已更新@Wyck

标签: javascript reactjs typescript graphql react-apollo


【解决方案1】:

如其他答案所述,这是已知问题 - "useLazyQuery execution function should return a promise #3499"

代替

    loadUsers({
      variables: {
        where: where
      },
    })
    .then(({ data }: any) => {
      if (data !== null && data !== undefined) {
      }
    })

你可以使用onCompleted选项

const [loadUsers, { loading, data }] = useLazyQuery(LoadUsersQuery, {
  onCompleted: ( data : any ) => {
    if (data !== null && data !== undefined) {
      // some action
    }
  }
});

【讨论】:

  • 由于我多次使用 loadUsers 查询(每次使用不同的参数),我不确定这是否可行。
  • 我尝试添加{ loading, data, error },但如果我在loadUsers 查询结束后添加console.log('Error: ' , error);,我总是不确定。即使出现错误。使用它的正确方法是什么?我找不到任何相关的例子。
  • 您可以从多个地方调用具有不同变量的变异 - 数据处理通常是相同的......如果data 可以,loading 可以是未定义的
  • 这并不能真正回答我的问题。那我还能如何访问错误消息?另外,例如,查询返回一个具有属性id的对象,那么我如何访问该属性?如果发生突变,我只会做data.loadUsers.id或其他事情,它会起作用,但在这种情况下不会。那么解决办法是什么?
  • error 在组件 fn 正文中可用(就像您之前尝试过的那样)... id?检查 response/console.log 吗? ...data.id?
【解决方案2】:

这取决于loadUsers 中究竟发生了什么,但您很可能忘记了那里的退货声明。

如果您更改 loadUsers 以返回正在加载的用户的承诺,您的代码应该开始正常工作。

【讨论】:

  • loadUsers 是一个 graphql 查询。我认为我不需要那里的退货声明,是吗?与第一个示例一样,updateUser() 也是一个 graphql 突变,它可以正常工作。你能看看我更新的问题,然后解释一下你的意思吗?
  • 这个答案是绝对正确的。不过,隐藏在 op 的示例中的是 loadUsers 来自外部方法,useLazyQuery 由 Apollo 提供。返回的方法没有返回 Promise。
  • 那么我还能如何访问错误消息呢?另外,例如,查询返回一个具有属性id的对象,那么我如何访问该属性?如果发生突变,我会做data.loadUsers.id或其他事情,它会起作用,但在这种情况下不会。那么解决方案是什么? @LMulvey
【解决方案3】:

如果您将the docs 视为useLazyQuery,它不会像useMutation 那样返回Promise,因此它们的行为不同。

您必须使用调用useLazyQuery 时返回的第二个参数(加载、数据),而不是依赖Promise。这就是为什么在您的编辑中,您的代码可以在没有 .then 的情况下工作。

【讨论】:

  • 我尝试添加{ loading, data, error },但如果我在 loadUsers 查询结束后添加console.log('Error: ' , error);,我总是不确定。即使出现错误。使用它的正确方法是什么?我找不到任何相关的例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
相关资源
最近更新 更多