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

时间:2016-02-20 14:59:19

标签: javascript meteor

如果可能的话,如何以对象作为参数调用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 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

$set: { coords,应该做什么?你不能这样做。您需要将该对象的内容分开并将其重新组合到$set中。假设coords = {lat: 1234, lng: 2345}(或类似),你会这样做:

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

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

$set: {
  coords: coords,

答案 2 :(得分:1)

Christian和Faysal的答案都包含有效的信息,我只是想稍微扩展一下:

您看到的实际异常Error: Match error: Expected number, got undefined正在发生,因为这行代码:

check(coords.latitude, Number);

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

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

因此,当你的check()方法检查currentLocation for coords.latitude时,它会抛出异常,因为coords.latitude的类型是undefined,而不是类型Number,就像你说它会在check()语句中一样。

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

答案 3 :(得分:0)

您从地理定位请求获取的对象实现了Coordinates接口。你不能假设任何其他事情。

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

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

_.keys

在Chrome的实施中,我认为这些属性是&#34;拥有&#34;更深入的原型链。 EJSON在克隆时依赖于下划线的> coordinates.hasOwnProperty("latitude") false > "latitude" in coordinates true 函数,后者又列出了对象自己的属性。

_.pick

由于creating a custom EJSON类型似乎不切实际,您可以像@ChristianFritz建议的那样使用或使用下划线> _.pick(coordinates, ['latitude', 'longitude', 'accuracy']) Object {latitude: 12.1212, longitude: 34.3434, accuracy: 50}

pip install Pillow