ilr*_*ein 10 javascript ecmascript-6 graphql
我的GraphQL客户端请求一个对象。
这是一个相当简单的对象:
type Element {
content: [ElementContent]
elementId: String
name: String
notes: String
type: String
createdAt: String
updatedAt: String
}
Run Code Online (Sandbox Code Playgroud)
使用特殊类型ElementContent,它很小,看起来像这样:
type ElementContent {
content: String
locale: String
}
Run Code Online (Sandbox Code Playgroud)
现在,当我在客户端上查询此对象时,顶层对象和底层对象均具有其他属性(如果我尝试按原样克隆主体,则会干扰更新对象);
值得注意的是,GraphQL似乎__typename在父对象中提供了一个属性,而在子对象中,它们也具有typename和一个Symbol(id)属性。
我很乐意将此对象复制到状态,在状态下更新,然后克隆状态并将其发送给我的update突变。但是,由于GraphQL本身提供的未知属性,我遇到了麻烦。
我试着做:
delete element.__typename 效果很好,但随后我还需要遍历子级对象(动态对象数组),并且可能还必须删除这些属性。
我不确定在此等式中是否缺少某些内容,或者我应该只是在代码中苦苦挣扎,然后进行循环+删除(最初尝试进行forEach循环时收到错误)。我尝试做的事情有更好的策略吗?还是我走在正确的道路上,只需要一些良好的循环代码即可清除不需要的属性?
Rig*_*men 24
有三种方法可以做到这一点
第一种方式
像这样更新客户端参数,它将忽略graphql中不需要的字段。
apollo.create({
link: http,
cache: new InMemoryCache({
addTypename: false
})
});Run Code Online (Sandbox Code Playgroud)
第二路
通过使用深省略包并将其用作中间件
const cleanTypeName = new ApolloLink((operation, forward) => {
if (operation.variables) {
operation.variables = omitDeep(operation.variables,'__typename')
}
return forward(operation).map((data) => {
return data;
});
});
Run Code Online (Sandbox Code Playgroud)
第三路
创建一个自定义的中间件并注入阿波罗
const cleanTypeName = new ApolloLink((operation, forward) => {
if (operation.variables) {
const omitTypename = (key, value) => (key === '__typename' ? undefined : value);
operation.variables = JSON.parse(JSON.stringify(operation.variables), omitTypename);
}
return forward(operation).map((data) => {
return data;
});
});
Run Code Online (Sandbox Code Playgroud)
并注入中间件
const httpLinkWithErrorHandling = ApolloLink.from([
cleanTypeName,
retry,
error,
http,
]);
Run Code Online (Sandbox Code Playgroud)
首选方法是“ 第三种方法”,因为它没有任何第三种依赖关系,也没有缓存性能问题
如果您想清除__typenameGraphQL 响应(从根及其子级),您可以使用graphql-anywhere包。
就像是:
const wipedData = filter(inputFragment, rcvData);
inputFragment是一个定义字段的片段(您可以在此处查看详细信息)rcvData是从 GraphQL 查询接收到的数据通过使用该filter函数,wipedData仅包含您需要作为突变输入传递的必填字段。