5

Maybe I don't understand javascript/coffee script as well as I thought but when I do this:

that.thing = thing
that.thing.title = "some title"
console.log(that.thing.title)
console.log(JSON.stringify(that.thing)

I get output:

some title

{"creation_date":"2011-09-09T00:40:03.742Z","_id":"4e6960638ec80519a0000013"}

The problem is I seem to lose the title property when I do the stringify (and later on when the function exists I seem to be having other interesting problems which I assume have to do with 'that' and this nested within multiple fxn calls).

(I had to do an ugly solution for now where I do that.thing = {} to solve my problem. Other problems I had to solve before included node.js + async + mongoose.find and this is all inside async.findEach)

When I do

console.log(that.thing.toJSON) 

I get:

function () { return this.toObject(); }

Thanks.

1
  • 3
    Are you sure that that.thing is not a horrific getter/setter thing? Commented Sep 9, 2011 at 20:43

3 Answers 3

6

This is because Model.find() is returning a MongooseDocument. If you want a plain JavaScript object, which you can add properties to, you need to specify the "lean" option:

Model.find().lean().exec(function (err, thing) {
    thing.title = "some title";
    console.log(JSON.stringify(thing));
});

This will work fine, provided you don't need to save the thing object again (as this is not a MongooseDocument, no getters and setters are applied).

Sign up to request clarification or add additional context in comments.

1 Comment

Just a hint. When you'd try to do this w/ .save() it wouldn't work. You'd then rather do thing.toObject() from the mongoose API. Your blog entry lead me and let me find this out. Thanks.
3

Since you mention mongoose it may be that that.thing is a special object with some specific properties.

There are two things that could be affecting this.

Either thing is actually a getter/setter with some horrible logic

Or more likely thing has a .toJSON method that writes the object to json and you havn't augmented or removed that method to make JSON.stringify work.

My default JSON.stringify calls the .toJSON method if it exists.

So a simple console.log(that.thing.toJSON); should identify your problem

Anyway what you really aught to be doing when you want to log data and make sure it logs what the current data is in a blocking fashion.

console.warn(util.inspect(that.thing));

4 Comments

Thanks for that. What I get is: " function () { return this.toObject(); } " I'm not 100% sure how to 'debug" javascript via node (haven't found a nicer debugger than Chrome's so far). How do I tell if this is some getter/setter?
@user885355 since it has toJSON method the thing JSON.stringify is serializing is that.thing.toObject() so that's why its broke.
I see, so ideally I would have to modify JSON.stringify to check for the .toJSON like you do. I'm not 100% sure how I would do this but I'll look into it. If I wanted to read the source for such calls in node would you recommend just going to the github repo / docs? @Raynos
@user885355 no-no. You need to murder .toJSON or don't use JSON.stringify for logging data. Just use console.warn(util.inspect(obj))
1

You are seeing "function () { return this.toObject(); }" because toJSON is a prototyped function.

That is, console.log(that.thing.toJSON) will print the function itself but console.log(that.thing.toJSON()) will print the value returned from the function. Adding the extra brackets will execute the function.

Try console.log(that.thing.toJSON()) and see if you get what you are looking for.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.