Apollo GraphQL 客户端不在查询中返回缓存的嵌套类型

标签 apollo apollo-client apollo-cache-inmemory

我正在执行查询以获取 PowerMeter 详细信息,其中包含名为 Project 的另一种类型。我这样写查询:

query getPowerMeter($powerMeterId: ID!) {
    powerMeter: powerMeter(powerMeterId: $powerMeterId) {
        id
        name
        registry
        project {
            id
            name
        }
    }
}

当我第一次执行查询时,成功返回project。问题是,当我使用相同的参数和默认的 fetchPolicy (cache-first) 执行后续查询时,不再返回 project

我该如何解决这个问题?

此外,我调用 readFragment 来检查 powerMeter 是如何保存在缓存中的,响应显示 powerMeterproject 已保存。

const frag = client.readFragment({
    fragment: gql`
        fragment P on PowerMeter {
            id
            name
            registry
            project {
                id
                name
            }
        }
    `,
    id: 'PowerMeter:' + powerMeterId,
});

功率计第一次返回

{
  "powerMeter":{
    "id":"7168adb4-4198-443e-ab76-db0725be2b18",
    "name":"asd123123",
    "registry":"as23",
    "project":{
      "id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
      "name":"ProjectName",
      "__typename":"Project"
    },
    "__typename":"PowerMeter"
  }
}

第一次调用电表后的片段

{
  "id":"7168adb4-4198-443e-ab76-db0725be2b18",
  "name":"asd123123",
  "registry":"as23",
  "project":{
    "id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
    "name":"ProjectName",
    "__typename":"Project"
  },
  "__typename":"PowerMeter"
}

Power Meter 第二次返回

{
  "powerMeter":{
    "id":"7168adb4-4198-443e-ab76-db0725be2b18",
    "name":"asd123123",
    "registry":"as23",
    "__typename":"PowerMeter"
  }
}

第二次调用功率计后的片段

{
  "id":"7168adb4-4198-443e-ab76-db0725be2b18",
  "name":"asd123123",
  "registry":"as23",
  "project":{
    "id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
    "name":"ProjectName",
    "__typename":"Project"
  },
  "__typename":"PowerMeter"
}

编辑 1:获取查询

下面的代码是我获取数据的方式。我使用的是 useApolloClient 而不是查询 Hook ,因为我使用的是 AWS AppSync 并且它尚不支持查询 Hook 。

import { useApolloClient } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import { useEffect, useState } from 'react';

export const getPowerMeterQuery = gql`
    query getPowerMeter($powerMeterId: ID!) {
        powerMeter: powerMeter(powerMeterId: $powerMeterId) {
            id
            name
            registry
            project {
                id
                name
            }
        }
    }
`;

export const useGetPowerMeter = (powerMeterId?: string) => {
    const client = useApolloClient();
    const [state, setState] = useState<{
        loading: boolean;
        powerMeter?: PowerMeter;
        error?: string;
    }>({
        loading: true,
    });

    useEffect(() => {
        if (!powerMeterId) {
            return setState({ loading: false });
        }

        client
            .query<GetPowerMeterQueryResponse, GetPowerMeterQueryVariables>({
                query: getPowerMeterQuery,
                variables: {
                    powerMeterId,
                },
            })
            .then(({ data, errors }) => {
                if (errors) {
                    setState({ loading: false, error: errors[0].message });
                }

                console.log(JSON.stringify(data));

                const frag = client.readFragment({
                    fragment: gql`
                        fragment P on PowerMeter {
                            id
                            name
                            registry
                            project {
                                id
                                name
                            }
                        }
                    `,
                    id: 'PowerMeter:' + powerMeterId,
                });

                console.log(JSON.stringify(frag));

                setState({
                    loading: false,
                    powerMeter: data.powerMeter,
                });
            })
            .catch(err => setState({ loading: false, error: err.message }));
    }, [powerMeterId]);

    return state;
};

编辑 2:获取策略详细信息

当我使用 fetchPolice 等于 cache-firstnetwork-only 时,错误仍然存​​在。当我使用 no-cache 时,我没有收到错误。

最佳答案

我认为这可能是解决方案: https://github.com/apollographql/apollo-client/issues/7050

可能为时已晚,但它可以帮助人们在未来解决这个问题。

当使用 apollo 客户端的 InMemoryCache 时,您似乎需要提供可能类型的列表,以便在使用 InMemoryCache 时可以正确完成片段匹配。

当联合类型很少且 API 非常稳定且不经常更改时,您可以手动执行此操作。 或者你自动生成这些类型到一个 json 文件中,你可以直接在 InMemoryCache 的 possibleTypes 配置中直接使用。

访问this link to the official docs了解如何去做。

干杯。

关于Apollo GraphQL 客户端不在查询中返回缓存的嵌套类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57897508/

相关文章:

activemq - 使用 stomp.js 而不是 sock.js 和 ActiveMQ-Apollo 似乎不起作用

graphql - 有没有办法在 devtool 网络选项卡中命名 graphql 请求?

apollo-client - 如何为 Apollo GraphQL 客户端禁用 InMemoryCache?

graphql - 为什么我们需要 `cacheRedirects`?

graphql - Apollo (graphQL)-如何在查询中发送对象数组

json - 如何在 swift 4 中使用 Graphql 获取 json 值数组?

graphql - Apollo 客户端的代码生成器在我的类型中添加了不需要的 "or null"

reactjs - Apollo 客户端乐观更新是否更改每个列表项的引用?

node.js - Apollo 查询缓存中的数据错误