代码之家  ›  专栏  ›  技术社区  ›  Ivo

Apollo boost-\uuuTypeName在查询中阻止新的变异

  •  1
  • Ivo  · 技术社区  · 6 年前

    我的meteor/react/apollo(带boost)项目有问题。当我从服务器上查询数据时,它会将类型名添加到查询中的每个对象和子对象中,但在我的情况下,它会产生一个主要问题,因为我通常会重用这些数据将它们发送给其他对象。现在另一个变异告诉我有一个错误,因为我的graphql模式中没有定义\uuu typename字段。

    我试图通过向apollo客户机添加addTypename:false字段来修复此问题,但没有改变任何内容(请注意,我使用的是apollo boost,这可能是它无法正常工作的原因):

    const client = new ApolloClient({
        uri: Meteor.absoluteUrl('graphql'),
        addTypename: false,
        request: operation =>
            operation.setContext(() => ({
                headers: {
                    authorization: Accounts._storedLoginToken()
                }
            }))
    })
    

    而且它似乎比即使它工作,它不是很优化。在我看来,在查询结果中添加一个字段是非常有问题的,我很惊讶在网上找不到任何清晰的解决方案。一些建议的解决方案,其中:

    • 向阿波罗添加中间件
    • 将\uuuTypeName字段添加到我的所有架构中。。。

    但它们似乎都不符合阿波罗提出的“简单城市”的要求。我希望有一个更简单,更符合逻辑的解决方案提供,但到目前为止,找不到任何。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Daniel Rearden    6 年前

    即使使用 apollo-client 而不是 apollo-boost ,你不应该设置 addTypename 除非你有令人信服的理由这么做。这个 __typename InMemoryCache

    Type 由查询和 Input Type 用作参数是完全不同的事情,即使作为Javascript对象,它们共享一个或多个字段。就像不能在模式中互换使用类型和输入类型一样,不应该期望它们可以在客户端互换使用。

    如果您正在使用某个查询填充一个或多个输入,然后在变异中使用这些输入的值,那么您可能已经将初始查询数据转换为组件状态,然后在变异中使用这些数据。在那种情况下, 或者任何其他不可编辑的字段可能不应该首先作为组件状态的一部分包括在内。

    function stripTypenames (value) {
        if (Array.isArray(value)) {
            return value.map(stripTypenames)
        } else if (value !== null && typeof(value) === "object") {
          const newObject = {}
          for (const property in value) {
              if (property !== '__typename') {
                newObject[property] = stripTypenames(value[property])
              }
          }
          return newObject
        } else {
          return value
        }
    }
    
        2
  •  0
  •   dmstack    5 年前

    here . '__“typename”可以用下面的helper函数删除

    const cleanedObject = omitDeep(myObject, "__typename")
    
    const omitDeep = (obj, key) => {
        const keys = Object.keys(obj);
        const newObj = {};
        keys.forEach((i) => {
          if (i !== key) {
            const val = obj[i];
            if (val instanceof Date) newObj[i] = val;
            else if (Array.isArray(val)) newObj[i] = omitDeepArrayWalk(val, key);
            else if (typeof val === 'object' && val !== null) newObj[i] = omitDeep(val, key);
            else newObj[i] = val;
          }
        });
        return newObj;
      };
    
    const omitDeepArrayWalk = (arr, key) => {
      return arr.map((val) => {
        if (Array.isArray(val)) return omitDeepArrayWalk(val, key)
        else if (typeof val === 'object') return omitDeep(val, key)
        return val
      })
    }
    
        3
  •  0
  •   Amin Noura    4 年前

    你不应该删除类型名。它们用于缓存,也用于联合类型。可能应该等阿波罗的消息。 不幸的是,我现在也有问题,我找不到一个适当的解决办法。起初我只是简单地删除所有类型名,但现在我对联合类型有问题。