Apolloクライアントを使用して、Graphqlを使用してサーバーにクエリを実行するアプリケーションを作成しています。 pythonサーバーがあり、ここでgraphqlクエリを実行して、データベースからデータをフェッチし、それをクライアントに返します。
クライアント用にカスタムNetworkInterfaceを作成しました。これは、カスタマイズされたサーバー要求を作成するのに役立ちます(デフォルトでは、ApolloClientはPOST指定したURLへの呼び出しを行います)。ネットワークインターフェイスに必要なのはフォームPromise<ExecutionResult>
の結果のpromiseを返すquery()メソッド。
サーバーを呼び出して、要求されたデータをフェッチできますが、それでも次のエラーが発生します。
Error: Network error: Error writing result to store for query
{
query something{
row{
data
}
}
}
Cannot read property 'row' of undefined
at new ApolloError (ApolloError.js:32)
at ObservableQuery.currentResult (ObservableQuery.js:76)
at GraphQL.dataForChild (react-apollo.browser.umd.js:410)
at GraphQL.render (react-apollo.browser.umd.js:448)
at ReactCompositeComponent.js:796
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (ReactCompositeComponent.js:795)
at ReactCompositeComponentWrapper._renderValidatedComponent (ReactCompositeComponent.js:822)
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:746)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:724)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:645)
at ReactCompositeComponentWrapper.performUpdateIfNecessary (ReactCompositeComponent.js:561)
at Object.performUpdateIfNecessary (ReactReconciler.js:157)
at runBatchedUpdates (ReactUpdates.js:150)
at ReactReconcileTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (Transaction.js:140)
at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
at Object.flushBatchedUpdates (ReactUpdates.js:172)
at ReactDefaultBatchingStrategyTransaction.closeAll (Transaction.js:206)
at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:153)
at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
at Object.enqueueUpdate (ReactUpdates.js:200)
エラーの考えられる原因と可能であれば解決策を知りたい。
同様のエラーが発生しました。クエリにidを追加して解決しました。たとえば、私の現在のクエリは
query {
service:me {
productServices {
id
title
}
}
}
私の新しいクエリは
query {
service:me {
**id**
productServices {
id
title
}
}
}
id
を含める必要があります。そうしないと、前述のエラーが発生します。
{
query something {
id
row {
id
data
}
}
}
数か月間、アプリのさまざまな部分でこの問題に取り組んだ後、この問題の原因を突き止めました。それに光を当てるのに役立ったのは、apollo-cache-inmemory
からapollo-cache-hermes
への切り替えでした。
私はこの問題を軽減するためにエルメスを実験しましたが、残念ながらapollo-cache-inmemory
と同じようにキャッシュを更新できません。しかし、奇妙なのは、apollo-cache-inmemory
とは異なり、hermesは非常にユーザーフレンドリーなメッセージを表示するということです。これにより、キャッシュに既に存在するオブジェクトタイプをIDで保存しようとしたが、新しいオブジェクトタイプにはそれがない場合に、キャッシュがこの問題に実際に遭遇することが判明しました。したがって、フィールドのクエリ時に細心の注意を払って一貫している場合、apollo-cache-inmemory
は正常に機能するはずです。 id
フィールドを特定のオブジェクトタイプのすべての場所で省略すると、問題なく動作します。どこでもid
フィールドを使用すると、正しく機能します。 idを使用したクエリと使用しないクエリを混在させると、この恐ろしいエラーメッセージでキャッシュが爆発します。
これはバグではありません-意図したとおりに動作しています。どこにも文書化されていません-これを参照してください spec 。私はアポロがこの制約をどこかで文書化したことを本当に望みます。
私には似たような問題がありました。
おそらくあなたのアプリが間違ったストアアドレスでストアに(ネットワークレスポンスデータ)を書き込もうとしていましたか?
player
をteam
に追加した後、ストアを更新していました:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id } };
const data = store.readQuery(addr);
stored.teams.players.Push(response.data.player));
store.writeQuery({...addr, data});
}
上記と同様のエラーが発生し始めました(Apollo 2.0.2を使用しています)
ストアを掘り下げた後、1つの変数meta
がデフォルトでnull
に設定されたQUERY_TEAM
リクエストに気付きました。 store "address"は、 *文字列化addr
は、レコードを識別します。だから私は上記のコードを変更してヌルを含めるようにしています:
// Apollo option object for `mutation AddPlayer`
update: (store, response) => {
const addr = { query: gql(QUERY_TEAM), variables: { _id, meta: null } };
const data = store.readQuery(addr);
data.teams.players.Push(response.data.player));
store.writeQuery({...addr, data});
}
そして、これは私の問題を修正しました。
* undefined
ではなくnull
にデフォルト設定すると、おそらくこの厄介なバグを回避できます(unverified)
私の問題は接線方向にのみ関連している可能性があるため、それでも問題が解決しない場合は、2つのアドバイスがあります。
最初、「レコード」が空になったときに警告するために、これらの3行をnode_modules/apollo-cache-inmemory/lib/writeToStore.js
に追加します。次に、_a
を調査して、何が問題かを理解します。
exports.writeResultToStore = writeResultToStore;
function writeSelectionSetToStore(_a) {
var result = _a.result, dataId = _a.dataId, selectionSet = _a.selectionSet, context = _a.context;
var variables = context.variables, store = context.store, fragmentMap = context.fragmentMap;
+if (typeof result === 'undefined') {
+ debugger;
+}
2番目、すべてのクエリ、ミューテーション、および手動ストア更新が期待する変数で保存されていることを確認します