对相同的变量应用突变后,<query>中将返回空数据对象

时间:2018-09-10 10:43:39

标签: graphql react-apollo

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"
    }
  }
}

2 个答案:

答案 0 :(得分:0)

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

这样做,我还必须执行refetch查询。

答案 1 :(得分:0)

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

在Apollo中,当一个变异返回在另一个查询中使用的数据时,该查询的结果将被更新。例如该查询返回所有待办事项

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
  • 用户:12的缓存仅包含{id:12},因为该突变未返回名称字段
  • 查询无法在不重新获取的情况下为所有者的名称字段提供准确的信息(默认情况下不会发生)。更新后返回data: {}

可能的解决方案

  • 更改突变的返回查询以包括查询所需的所有字段。
  • 在突变后(通过refetchQueries)触发对查询的重新引用,或包含缓存所需内容的其他查询
  • 手动更新缓存

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

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

@clément-prévost的帽子提示提供了线索:

  

获取相同实体的查询和变异必须查询相同的实体   领域。这是避免本地缓存问题的方法。