为什么服务器在使用非空对象调用 Meteor.method 时得到一个空对象



如果可能的话,如何调用带有对象作为参数的 Meteor 方法?

如果有帮助,这就是我正在努力解决的问题

我有方法:

'user.some.update.position'(coords) {
    console.log('method: ', 'user.some.update.position');
    console.log('this.userid: ', this.userId);
    console.log('coords: ', coords);
    check(coords, Object);
    check(coords.latitude, Number);
    check(coords.longitude, Number);
    check(coords.accuracy, Number);
    if (!this.userId)
      throw new Meteor.Error('Not logged in', 'You are not logged in, please log in');
    Meteor.users.update({
      _id: this.userId
    }, {
      $set: {
        coords,
        lastUpdated: new Date()
      }
    });
    return coords;
  }

我想像这样从客户端调用:

> var coords = Geolocation.currentLocation().coords
undefined
> coords
Coordinates {latitude: 58.2441766, longitude: 8.376727899999999, altitude: null, accuracy: 25, altitudeAccuracy: null…}
> Meteor.call('user.some.update.position', coords, function(err, res) {if(err) console.log('err: ', err); if(res) console.log('res: ', res);})
undefined
VM7572:2 err:  errorClass {error: 400, reason: "Match failed", details: undefined, message: "Match failed [400]", errorType: "Meteor.Error"}

但是当我这样做时,服务器抱怨coords是一个空对象,如下所示:

method:  user.some.update.position
I20160220-15:49:34.226(1)? this.userid:  nHqj3zaSWExRmqBZq
I20160220-15:49:34.226(1)? currentLocation:  {}
I20160220-15:49:34.227(1)? Exception while invoking method 'user.some.update.position' Error: Match error: Expected number, got undefined
I20160220-15:49:34.227(1)?     at Object.check (packages/check/match.js:33:1)
I20160220-15:49:34.228(1)?     at [object Object]._meteorMeteor.Meteor.methods.user.some.update.position (server/methods/drivers.js:36:5)
I20160220-15:49:34.228(1)?     at packages/check/match.js:103:1
I20160220-15:49:34.228(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20160220-15:49:34.228(1)?     at Object.Match._failIfArgumentsAreNotAllChecked (packages/check/match.js:102:1)
I20160220-15:49:34.228(1)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1695:18)
I20160220-15:49:34.228(1)?     at packages/ddp-server/livedata_server.js:708:19
I20160220-15:49:34.228(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20160220-15:49:34.228(1)?     at packages/ddp-server/livedata_server.js:706:40
I20160220-15:49:34.229(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20160220-15:49:34.229(1)? Sanitized and reported to the client as: Match failed [400]

客户抱怨:

err:  errorClass {error: 400, reason: "Match failed", details: undefined, message: "Match failed [400]", errorType: "Meteor.Error"}

编辑:我正在使用ES6和对象解构。

从您的错误消息中可以清楚地看出,您的对象中没有任何内容。 请查看错误消息的第 4 行,currentLocation不包含任何属性。发送有效对象将解决问题。

$set: { coords,应该做什么? 你不能那样做。您需要将该对象的内容拆开,然后将其重新组合到$set中。假设coords = {lat: 1234, lng: 2345}(或类似),您将执行以下操作:

$set: {
  lat: coords.lat,
  lng: coords.lng,
  ...

或者您可以将其添加为子对象;

$set: {
  coords: coords,

克里斯蒂安和费萨尔的回答都包含有效信息,我只想稍微扩展一下:

您看到的实际异常Error: Match error: Expected number, got undefined 由于以下代码行而发生:

check(coords.latitude, Number); .

在控制台日志中,您可以看到坐标只是一个空对象:

I20160220-15:49:34.226(1)? currentLocation: {}

因此,当您的 check() 方法检查 coords.纬度的当前位置时,它会抛出异常,因为 coords.latitude 的类型是 undefined,而不是你所说的 Number 类型,它会在 check() 语句中。

一旦你解决了这个问题,克里斯蒂安指出,由于你的更新声明,你会得到另一个错误。 MongoDB的$set要求你传入一个带有模式{ $set: { <field1>: <value1>, ... } }的对象。 你正在传入:{ $set: {}, lastUpdated: <A valid Date> } . 由于该空对象与$set预期的field: value架构不匹配,因此将引发异常。 正如他所说,您需要将该对象解析为单个属性或将其传递给属性本身。

您从地理位置请求中获取的对象实现坐标接口。你不能对它做任何其他假设。

在您的情况下,该对象可能无法通过 EJSON 序列化,因此不能按原样用作 Meteor 方法调用参数。

方法调用例程调用EJSON.clone(),给定Coordinates对象,它返回一个空对象。

> EJSON.clone(coordinates)
Object {}

Chrome的实现中,我假设这些属性在原型链的更深处"拥有"。EJSON 在克隆时依赖于下划线的_.keys函数,而下划线又会列出对象自身的属性。

> coordinates.hasOwnProperty("latitude")
false
> "latitude" in coordinates
true

由于为其创建自定义 EJSON 类型似乎不切实际,因此您可以按照@ChristianFritz建议或使用下划线的_.pick

> _.pick(coordinates, ['latitude', 'longitude', 'accuracy'])
Object {latitude: 12.1212, longitude: 34.3434, accuracy: 50}

最新更新