Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Returning a custom EJSON object from a method doesn't seem to work. #731

Closed
sjoerdvisscher opened this issue Feb 22, 2013 · 2 comments
Closed

Comments

@sjoerdvisscher
Copy link

sjoerdvisscher commented Feb 22, 2013

I wanted to play with EJSON in the new 0.5.7 a bit, so I created a new meteor project and added the following bit of js. (I've deployed it on http://ejson-github-issue.meteor.com)

if (Meteor.isClient) {
  Template.hello.greeting = function () {
    return "Click the button";
  };

  Template.hello.events({
    'click input' : function () {
      Meteor.call("getDog", new Dog("brown", "stinky"), function(_, dog) {
        console.log(dog.toString(), dog);
      });
    }
  });
}

function Dog(fur, breath) {
  this.fur = fur;
  this.breath = breath;
}
Dog.prototype.clone = function() {
  console.log("cloning: " + this)
  return new Dog(this.fur, this.breath);
}
Dog.prototype.equals = function(that) {
  console.log("equals")
  return this.fur == that.fur && this.breath == that.breath;
}
Dog.prototype.typeName = function() {
  console.log("typeName")      
  return "Dog";
}
Dog.prototype.toJSONValue = function() {
  console.log("serializing: " + this)
  return {
    fur: this.fur,
    breath: this.breath
  }
}
Dog.prototype.toString = function() {
  return "A " + this.fur + " dog with " + this.breath + " breath."
}

EJSON.addType("Dog", function(obj) {
  console.log("parsing: ", obj)
  return new Dog(obj.fur, obj.breath);
})

if (Meteor.isServer) {
  Meteor.methods({
    getDog: function(dog)
    {
      console.log("Got: ", dog.toString())
      return new Dog(dog.fur, dog.breath);
    }
  });
}

A click on the button sends a Dog object to the server, and the server sends a Dog object back.

What I see in the console on the client is:

cloning: A brown dog with stinky breath. ejson.js:20
typeName ejson.js:28
typeName ejson.js:28
serializing: A brown dog with stinky breath. ejson.js:32
[object Object] Object {fur: "brown", breath: "stinky"} ejson.js:9

And on the server:

parsing:  { fur: 'brown', breath: 'stinky' }
Got:  A brown dog with stinky breath.
cloning: A brown dog with stinky breath.

So when sending the Dog object from client to server, the object is first cloned, then serialized on the client, and then parsed on the server, and the method receives a proper Dog object.

But when sending the Dog object from server to client, only the cloning happens. typeName is never called, and serializing and parsing doesn't happen. So the clients receives a plain JSON object.

@glasser
Copy link
Contributor

glasser commented Feb 27, 2013

Good catch! The bug appears to be in Meteor._stringifyDDP:

  // adjust types to basic
  _.each(['fields', 'params', 'result'], function (field) {
    if (_.has(copy, field))
      EJSON._adjustTypesToJSONValue(copy[field]);
  });

EJSON._adjustTypesToJSONValue doesn't actually work if copy[field] itself is an extended type (as opposed to an element inside it, which is what happens for fields and params).

@ghost ghost assigned sixolet Feb 27, 2013
sixolet pushed a commit that referenced this issue Feb 28, 2013
Tests for returning a scalar EJSON type from a method
@sixolet
Copy link

sixolet commented Feb 28, 2013

Fixed on devel as of 88f2969

@sixolet sixolet closed this as completed Feb 28, 2013
StorytellerCZ pushed a commit that referenced this issue Sep 18, 2021
Update mocha to the latest version 🚀
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants