Javascript 为什么服务器在使用非空对象调用Meteor.method时得到空对象?
如果可能的话,我如何用对象作为参数调用Meteor方法 如果有帮助的话,这就是我正在努力解决的问题 我的方法是:Javascript 为什么服务器在使用非空对象调用Meteor.method时得到空对象?,javascript,meteor,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(co
'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,
Christian和Faysal的回答都包含了有效的信息,我只想对它们进行一点扩展: 您看到的实际异常,
Error:Match Error:Expected number,get undefined
,是由于以下代码行而发生的:
检查(坐标、纬度、数字);
在控制台日志中,您可以看到coords只是一个空对象:
I20160220-15:49:34.226(1)?当前位置:{}
因此,当您的check()方法检查currentLocation中的coords.latitude时,它会抛出异常,因为coords.latitude的类型为undefined,而不是像您在check()语句中所说的类型Number
一旦修复,Christian指出,由于update语句,您将遇到另一个错误。要求您传入一个模式为
{$set:{:,…}
的对象。您要传入:{$set:{},lastUpdated:}
。因为空对象与字段:value
schema$set不匹配,它将抛出一个异常。正如他所说,您需要将该对象解析为单个属性,或者将其传递给属性本身。从地理位置请求获取的对象将实现该接口。您可以关于这件事,我不作任何假设
在您的例子中,对象可能无法通过EJSON序列化,因此不能像现在这样用作Meteor方法调用参数
方法调用例程调用EJSON.clone()
并给定坐标
对象,它返回一个空对象
> EJSON.clone(coordinates)
Object {}
在Chrome的实现中,我假设属性在原型链的更深处是“拥有的”。EJSON在克隆时依赖下划线的\ukeys
函数,该函数依次列出对象自己的属性
> coordinates.hasOwnProperty("latitude")
false
> "latitude" in coordinates
true
因为它的类型似乎不现实,所以您可以按照@ChristianFritz的建议或使用下划线的
> _.pick(coordinates, ['latitude', 'longitude', 'accuracy'])
Object {latitude: 12.1212, longitude: 34.3434, accuracy: 50}
我不明白。这不是一个你正在破坏任何东西的实例。这里面没有赋值(=
)。对不起,我在考虑对象速记,所以如果我是正确的,{coords}应该与{coords:coords}相同好的,我明白你们想说的了,但我想你们可能误解了我的代码,更简单地说,如果我这么做:var coords=Geolocation.currentLocation().coords;console.log(coords);VM6643:2坐标{}未定义的Meteor.call('user.some.update.position',coords,function(err,res){(err)console.log('err:',);if(res)console.log('res:',res);})未定义的VM6644:2错误:error类{error:400,原因:“匹配失败”,详细信息:未定义,消息:“匹配失败[400]”,错误类型:“Meteor.error”}
这可能解释了我正在做的事情更简单,仍然得到相同的结果如果coords为空,则更改检查(coords.latitude,Number);检查(坐标经度,数字);检查(坐标准确度,数字);
收件人:检查(坐标经度,匹配可选(数字));检查(坐标经度,匹配可选(数字));检查(坐标准确度,匹配可选(数字))
不,coords为null不合适,如果我的问题不清楚,我很抱歉,但我需要帮助的是,当我清楚地将坐标对象传递给Meteor.call()时,找出coords在服务器上是空对象的原因在客户端,我在我的op中更新了客户端代码以更好地反映这一点。我认为所有回答者都感到困惑的是,在客户端和服务器上,您的坐标看起来都是空的。我只是想再次尝试说服您,coords对象在客户端上不是空的,而仅在客户端上是空的服务器:var coords2={accurity:25,lattde:58.24,经度:8.37}未定义的Meteor.call('user.some.update.position',coords2,function(err,res){if(err)console.log('err:',err err);if(res)console.log('res:',res;})未定义的VM7797:2 error:error类{error:400,原因:“匹配失败”,详细信息:未定义,消息:“匹配失败[400],errorType:“Meteor.Error”}
并且我在服务器上仍然得到相同的响应。我用新的客户端代码更新了op,这清楚地反映了我正在将坐标对象传递给Meteor.call('user.some.update.position')),我似乎不明白为什么在服务器上执行该方法时它应该是空的。您是否尝试过Christian的第一个建议(仅显式发送lat、lon和accurity)?您还可以尝试记录接收到的数据,并使用开发工具(或DDP inspector实用程序)查看通过websocket发送的内容。非常感谢!我通过手动克隆对象解决了这个问题。Yoy是第一个真正回答我问题的人,而不是对代码的其他部分吹毛求疵。不客气。我不会称之为吹毛求疵,因为他们确实提出了有效的观点(仍然有效),而且这个问题隐藏得很深。我会的