应用突变后 <Query> 中的空数据对象 returns

Empty data object returns in <Query> after mutation is applied for the same

Github Issue Posted Here

"apollo-boost": "^0.1.13",
"apollo-link-context": "^1.0.8",
 "graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"react-apollo": "^2.1.11",

当前代码结构

<div>
<Query
    query={FETCH_CATEGORIES_AUTOCOMPLETE}
    variables={{ ...filters }}
    fetchPolicy="no-cache"
  >
    {({ loading, error, data }) => {
      console.log('category', loading, error, data); // _______Label_( * )_______
      if (error) return 'Error fetching products';

      const { categories } = data;

      return (
        <React.Fragment>
          {categories && (
            <ReactSelectAsync
              {...this.props.attributes}
              options={categories.data}
              handleFilterChange={this.props.handleCategoryFilterChange}
              loading={loading}
              labelKey="appendName"
            />
          )}
        </React.Fragment>
      );
    }}
  </Query>

<Mutation mutation={CREATE_CATEGORY}>
  {createCategory => (
    <div>
    // category create form
    </div>
  )}
</Mutation>
</div>

行为

最初,查询获取数据,我得到数据中的类别列表 given in Label_( * )。 输入表单详细信息后,提交成功。 Issue:然后,突然,在Label_( * )中,数据对象是空的。

我该如何解决这个问题?

编辑

这些是回复:

类别 GET

{
  "data": {
    "categories": {
      "page": 1,
      "rows": 2,
      "rowCount": 20,
      "pages": 10,
      "data": [
        {
          "id": "1",
          "appendName": "Category A",
          "__typename": "CategoryGETtype"
        },
        {
          "id": "2",
          "appendName": "Category B",
          "__typename": "CategoryGETtype"
        }
      ],
      "__typename": "CategoryPageType"
    }
  }
}

类别创建

{
  "data": {
    "createCategory": {
      "msg": "success",
      "status": 200,
      "category": {
        "id": "21",
        "name": "Category New",
        "parent": null,
        "__typename": "CategoryGETtype"
      },
      "__typename": "createCategory"
    }
  }
}

fetchPolicy更改为cache-and-network后。它解决了这个问题。 Link to fetchPolicy Documentation

这样做,我还必须执行重新获取查询。

(我在遇到类似问题时遇到了这个问题,现在我已经解决了)

在 Apollo 中,当 returns 数据在不同的查询中使用时,该查询的结果将被更新。例如此查询 return 所有待办事项

query { 
  todos { 
    id
    description
    status
  }
}

然后,如果我们将待办事项标记为已完成并带有变更

mutation CompleteTodo {
  markCompleted(id: 3) { 
    todo { 
      id
      status
    }
  }
}

结果是

{ 
  todo: {
    id: 3,
    status: "completed"
    __typename: "Todo" 
  }
}

然后 ID 为 1 的待办事项将更新其状态。当突变告诉查询它已经过时,但没有提供足够的信息来更新查询时,问题就来了。例如

query {
  todos { 
    id
    description
    status
    owner { 
      id
      name
    }
  }
}

mutation CompleteTodo {
  assignToUser(todoId: 3, userId: 12) { 
    todo { 
      id
      owner {
        id
      }
    }
  }
}

示例结果:

{ 
  todo: {
    id: 3,
    owner: { 
      id: 12, 
      __typename: "User"
    }, 
    __typename: "Todo"
  }
}

想象一下,您的应用以前对 User:12 一无所知。事情是这样的

  • Todo:3 的缓存知道它现在拥有所有者 User:12
  • User:12 的缓存仅包含 {id:12},因为突变没有 return 名称字段
  • 如果不重新获取(默认情况下不会发生),查询就无法为所有者的名称字段提供准确的信息。它更新为 return data: {}

可能的解决方案

  • 更改突变的 return 查询以包括查询需要的所有字段。
  • 在更改后触发查询的重新获取(通过 refetchQueries),或包含缓存所需的所有内容的不同查询
  • 手动更新缓存

其中,第一个可能是最简单和最快的。在 apollo 文档中对此进行了一些讨论,但我没有看到任何描述数据变空的特定行为的内容。

https://www.apollographql.com/docs/angular/features/cache-updates.html

感谢@clément-prévost 提供线索的评论:

Queries and mutations that fetch the same entity must query the same fields. This is a way to avoid local cache issues.