繁体   English   中英

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

[英]Why is the server getting an empty object when calling Meteor.method with a non-empty object?

如果有可能,如何以对象为参数调用流星方法?

这是我正在努力解决的问题

我有方法:

'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和对象分解。

从错误消息中很明显,您的对象中没有任何内容。 请查看错误消息的第四行, currentLocation包含任何属性。 发送有效的对象将解决问题。

$set: { coords,是什么$set: { coords,应该做什么? 你不能那样做。 您需要拆开该对象的内容,然后将其放回$set 假设coords = {lat: 1234, lng: 2345} (或类似名称),您可以这样做:

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

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

$set: {
  coords: coords,

克里斯蒂安(Christian)和费萨尔(Faysal)的答案都包含有效信息,我只想对它们作一点扩展:

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

check(coords.latitude, Number);

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

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

因此,当您的check()方法检查currentLocation中的coords.latitude时,它会引发异常,因为coords.latitude的类型未定义,而不是Number类型,就像您所说的那样在check()语句中。

解决此问题后,克里斯汀·克里斯汀指出,由于您的更新语句,您还会收到另一个错误。 MongoDB的$ set要求您传入具有模式{ $set: { <field1>: <value1>, ... } } 您要传入: { $set: {}, lastUpdated: <A valid Date> } 因为该空对象与该field: value不匹配field: value模式$ set需要,所以它将引发异常。 正如他所说,您将需要将该对象解析为单独的属性,或者将其传递给属性本身。

您从地理位置请求中获取的对象将实现Coordinates接口。 您不能对此承担其他任何责任。

在您的情况下,该对象可能无法通过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}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM