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

ObjectWrap and JSON.stringify #410

Closed
atoy40 opened this issue Dec 17, 2018 · 13 comments
Closed

ObjectWrap and JSON.stringify #410

atoy40 opened this issue Dec 17, 2018 · 13 comments
Labels

Comments

@atoy40
Copy link

atoy40 commented Dec 17, 2018

Hello,

I' like to know if it is possible to get something from a JSON.stringify() call on an "ObjectWraped" instance ?
Do I have to implement specific methods into my object code (i"ve try to implement getOwnPropertyNames and set property enumerable) ?

Anthony.

@NickNaso
Copy link
Member

Hi @atoy40 ,
you coluld retrieve JSON.stringify from the global object like reported below:

// In your native function
Napi::Object json = env.Global().Get("JSON").As<Object>();
Napi::Function stringify = json.Get("stringify").As<Function>();

// Use stringify function
stringify.Call(json, { /*your json object*/ }).As<String>();

Hope to be helpful.

@atoy40
Copy link
Author

atoy40 commented Dec 17, 2018

@NickNaso thanks, but that's not what i'm searching for :)
My problem is this : I've a c++ object wrapped into a node object through ObjectWrap. this object expose some acccessors. Then, in my javascript code, if I try JSON.stringify(an_instance_of_myobject);, i only get MyObject {}

The question, is it possible to get properties of my object into the json return value ?.

@NickNaso
Copy link
Member

@atoy40 Sorry I misunderstood your need. I try later to create an example for you. I will start from this example https://github.com/nodejs/node-addon-examples/blob/master/6_object_wrap/node-addon-api/myobject.cc
is it good for you?

@atoy40
Copy link
Author

atoy40 commented Dec 17, 2018

@NickNaso yes, I started from this kind of example to define my object, so it is looking like this one ... but with accessors instead of methods.

@atoy40
Copy link
Author

atoy40 commented Dec 17, 2018

@NickNaso I've found some results. By implementiing two functions : toJSON for the json stringify, and a function assigned to the symbol "nodejs.util.inspect.custom" for console.log display.

@DaAitch
Copy link
Contributor

DaAitch commented Dec 26, 2018

@atoy40 You need to go through the rules what JSON.stringify(...) is doing with the value parameter.
toJSON seems to be the first check so simply implement that function.

@sziraqui
Copy link

@atoy40 can you share your implementation of those two methods?

@vpaladino778
Copy link

Hi @atoy40 ,
you coluld retrieve JSON.stringify from the global object like reported below:

// In your native function
Napi::Object json = env.Global().Get("JSON").As<Object>();
Napi::Function stringify = json.Get("stringify").As<Function>();

// Use stringify function
stringify.Call(json, { /*your json object*/ }).As<String>();

Hope to be helpful.

Unrelated to this issue, but I had a question for @NickNaso

I'm trying to utilize your method here to converting a Napi::Object into a string containing json

void my JSFunc(const Napi::CallbackInfo& info) {
  Napi::Object myObject = info[0].As<Napi::Object>();

  Napi::Object json = env.Global().Get("JSON").As<Napi::Object>();
  Napi::Function jsonStringify = json.Get("parse").As<Napi::Function>();

  Napi::String stringValue = jsonStringify.Call(json, {myObject }).As<Napi::String>();

  cout << stringValue.Utf8Value();;
}

For some reason i'm receiving "FATAL ERROR: Error::New napi_get_last_error_info" as an error

@vpaladino778
Copy link

I was able to figure out my issue. For anyone else that comes across this, I realized this line:

Napi::Function jsonStringify = json.Get("parse").As<Napi::Function>();

Should have been:

Napi::Function jsonStringify = json.Get("stringify").As<Napi::Function>();

Silly mistake on my part, but just wanted to share.

@NickNaso
Copy link
Member

NickNaso commented Jan 15, 2020

Hi @vpaladino778,
I'm happy to see that you solved the problem. i prepared an example on which I illustrated the use of JSON.parse and JSON.stringify

#include <napi.h>

Napi::String JSONStringify(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::Object json_object = info[0].As<Napi::Object>();
  Napi::Object json = env.Global().Get("JSON").As<Napi::Object>();
  Napi::Function stringify = json.Get("stringify").As<Napi::Function>();
  return stringify.Call(json, { json_object }).As<Napi::String>();
}

Napi::Object JSONParse(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::String json_string = info[0].As<Napi::String>();
  Napi::Object json = env.Global().Get("JSON").As<Napi::Object>();
  Napi::Function parse = json.Get("parse").As<Napi::Function>();
  return parse.Call(json, { json_string }).As<Napi::Object>();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports["jsonStringify"] =  Napi::Function::New(env, JSONStringify);
  exports["jsonParse"] = Napi::Function::New(env, JSONParse);          
  return exports;
}

NODE_API_MODULE(json, Init)
'use strict'

const assert = require('assert')
const addon = require('bindings')('json');

const jsonObj = { a: 1 }
const jsonString = JSON.stringify(jsonObj)

assert.strictEqual(addon.jsonStringify(jsonObj), jsonString)
assert.deepStrictEqual(addon.jsonParse(jsonString), jsonObj)

I provide to attach the code complete code example.
json.zip

@vpaladino778
Copy link

@NickNaso

Hi Nick,

Thanks so much for this, it was helpful to me. It was very kind of you to take the time to put together this example.

@github-actions
Copy link

This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.

@github-actions github-actions bot added the stale label Dec 18, 2020
@mhdawson
Copy link
Member

Going to close this as it looks like the discussion has run its course and the questions were answered. Please let us know if you think this was not the right thing to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants