[Solved] Meteor.publish doesn't recognize methods of an object passed as an argument in subscribe call


#1

issue
Server (coffee)

Meteor.publish 'posts', (args)->
 userId = @userId
 Posts.find(cityId:args.cityId(userId))

Client

obj=
  cityId:(userId)->Users.findOne(userId).city
Meteor.subscribe 'posts', obj

Throws Exception from sub posts id WcuyuY6eWNBxFw8yK TypeError: Object #<Object> has no method cityId in server console.

Has anyone run into this?


#2

well, DDP support only E-JSON and function is not E-JSON type.
You need to pass normal arguments, not functions.


#3

How unfortunate… .


#4

Since that argument is sent over the internet, there is literally no way to send functions. It would also be a bad idea to let the client send arbitrary code to the server.


#5

i could think of use cases though. say you have a developer game of sorts, or even just a sort of shared live coding IDE, perhaps you pass the functions as strings to the server–the server never evals them–and then passes the functions on to other clients as part of a collection. the other clients can then eval them. …in fact, that’s exactly what any collaborative coding environment does.


#6

Yes, you could do that. But I don’t think that’s the situation that the OP was in. Sending JavaScript code as a string from a client is a reasonable thing to do if your app involves users writing custom code on the frontend, but it’s not reasonable to use that code as a trusted source of application logic without carefully sandboxing it.


#7

In that case I cannot make a universal object to pass to multiple pubs, and have to multiplicate my get cityId code - how very unfortunate…


#8

Why not do (using collection helpers)

Users.helpers({
  posts() {
    return Posts.find({ cityId: Users.findOne(this.userId).city });
  }
});
Meteor.publish 'posts', ->
  return Users.findOne(userId).posts();

Does that solve your issue?


#9

Yep) Thank you, Sashko.
I guess, that helper will be solely for pubs, as it uses @userId.


#10

Wouldn’t Users have a userId field? In that case, it would work anywhere.