如何在 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:传递查询变量

React - 带有输入变量的 Apollo 客户端查询

如何正确地将变量传递给 apollo useQuery?

如何在我的 vue 模板脚本中有条件地调用 apollo 客户端?

Apollo 客户端没有读取使用 useQuery 钩子传入的变量

当变量发生变化时,Apollo 客户端缓存不会在查询中更新