如何在 Apollo 客户端中传递地理查询变量(使用 React Native / Hasura GraphQL)
Posted
技术标签:
【中文标题】如何在 Apollo 客户端中传递地理查询变量(使用 React Native / Hasura GraphQL)【英文标题】:How to pass a geography query variable in Apollo client (using React Native / Hasura GraphQL) 【发布时间】:2020-08-31 21:05:39 【问题描述】:我有以下 gql 查询:
query nearby_users($point: geography!)
users(where: location: _st_d_within: distance: 200000, from: $point)
id
location
在 Hasura 的 API 控制台中,我将以下内容作为查询变量:
"point":
"type" : "Point",
"coordinates": [43, 11]
反过来,我得到以下输出(这就是我要找的!):
"data":
"users": [
"id": 3,
"location":
"type": "Point",
"crs":
"type": "name",
"properties":
"name": "urn:ogc:def:crs:EPSG::4326"
,
"coordinates": [
43.75049,
11.03207
]
,
"id": 1,
"location":
"type": "Point",
"crs":
"type": "name",
"properties":
"name": "urn:ogc:def:crs:EPSG::4326"
,
"coordinates": [
43.75049,
11.03207
]
]
但是,当我使用 Apollo 客户端将内容迁移到 React Native 时,事情变得有些棘手。
我创建一个点如下:
const point = JSON.stringify(
"point":
"type" : "Point",
"coordinates": [43, 11]
);
然后查询客户端:
client.query( query: GET_USERS_NEARBY, variables: point )
但是,我收到以下错误:
GraphQL error: postgres query error
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:136968:30 in ApolloError
- node_modules/@apollo/client/apollo-client.cjs.js:2465:62 in <anonymous>
* [native code]:null in forEach
- node_modules/@apollo/client/apollo-client.cjs.js:2060:12 in QueryInfo.prototype.notify
* [native code]:null in forEach
- node_modules/@apollo/client/apollo-client.cjs.js:2720:8 in QueryManager.prototype.broadcastQueries
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:139848:35 in <unknown>
- node_modules/zen-observable/lib/Observable.js:321:16 in _this2.subscribe$argument_0.next
- node_modules/zen-observable/lib/Observable.js:134:6 in notifySubscription
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:143391:23 in onNotify
- node_modules/zen-observable/lib/Observable.js:234:11 in next
* [native code]:null in forEach
- node_modules/@apollo/client/apollo-client.cjs.js:1911:28 in inner.subscribe$argument_0.next
- node_modules/subscriptions-transport-ws/dist/client.js:144:37 in executeOperation$argument_1
- node_modules/subscriptions-transport-ws/dist/client.js:510:16 in SubscriptionClient.prototype.processReceivedData
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:150646:34 in <unknown>
- node_modules/event-target-shim/dist/event-target-shim.js:818:39 in EventTarget.prototype.dispatchEvent
- node_modules/react-native/Libraries/WebSocket/WebSocket.js:232:27 in _eventEmitter.addListener$argument_1
- node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js:190:12 in emit
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:436:47 in __callFunction
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:111:26 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:110:17 in __guard$argument_0
* [native code]:null in callFunctionReturnFlushedQueue
经过大量实验,很明显错误来自我的观点常数。
我尝试删除 JSON.stringify 如下:
const point =
"point":
"type" : "Point",
"coordinates": [43, 11]
;
这会导致网络类型错误:
Network error: key "type" not present
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:136968:30 in ApolloError
- node_modules/@apollo/client/apollo-client.cjs.js:2465:62 in <anonymous>
* [native code]:null in forEach
- node_modules/@apollo/client/apollo-client.cjs.js:2060:12 in QueryInfo.prototype.notify
* [native code]:null in forEach
- node_modules/@apollo/client/apollo-client.cjs.js:2720:8 in QueryManager.prototype.broadcastQueries
* http://192.168.0.201:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:139313:45 in <unknown>
- node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
- node_modules/promise/setimmediate/core.js:123:25 in setImmediate$argument_0
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:146:14 in _callTimer
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:194:17 in _callImmediatesPass
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:458:30 in callImmediates
* [native code]:null in callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:407:6 in __callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:143:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:142:17 in __guard$argument_0
* [native code]:null in flushedQueue
* [native code]:null in callFunctionReturnFlushedQueue
有人知道我做错了什么吗?真的很感激:)
【问题讨论】:
只是const point = point: type : "Point", coordinates: [43, 11] ;
和variables: point
?
【参考方案1】:
问题是您正在将变量转换为字符串。 Hasura 期待一个 javascript 对象,而不是一个字符串。
从您的代码中删除JSON.stringify
:
const point = JSON.stringify(
"point":
"type" : "Point",
"coordinates": [43, 11]
);
只留下 JavaScript 对象:
const point =
"point":
"type" : "Point",
"coordinates": [43, 11]
;
【讨论】:
以上是关于如何在 Apollo 客户端中传递地理查询变量(使用 React Native / Hasura GraphQL)的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS/Javascript/Graphql/React-apollo:传递查询变量
如何在我的 vue 模板脚本中有条件地调用 apollo 客户端?