javascriptc++castingnode-addon-api

Reading N-API object into C++ primitive


I've created a simple N-API module starting from the ObjectWrap boilerplate of generator-napi-module, and successfully passed data (an array containing objects with string, number and boolean properties) to JS. However, I'm unable to parse the properties of one of the same objects passed back to the native code; specifically, creating a uint32_t value from a property (a number) of the passed object.

Suppose an array of objects is created and passed to JS:

Napi::Value ObjectWrapAddon::GetSomeList(const Napi::CallbackInfo& info){
  Napi::Env env = info.Env();
  native_struct_one *data = NULL;
  native_struct_two opts = { TRUE,FALSE,FALSE };
  int retVal = native_lib_method(&data, &opts);
  if(retVal!=OK) {
    return Napi::Array::New(env); // return empty array
  }
  Napi::Array arr = Napi::Array::New(env);
  uint32_t i = 0;
  do {
    Napi::Object tempObj = Napi::Object::New(env);
    tempObj.Set("someProp", data->someVal);
    arr[i] = tempObj;
    i++;
    data = data->next;
  } while(data);
  return arr;
}

Then one of those objects is passed to a native function call:

Napi::Value ObjectWrapAddon::OtherMethod(const Napi::CallbackInfo& info){
  Napi::Env env = info.Env();
  Napi::Object obj = info[0].As<Napi::Object>();
  uint32_t temp = obj.Get("someProp").As<Napi::Number>();
  return Napi::Number::New(env, temp);
}

This builds fine, but the above OtherMethod() gives an A number was expected error at uint32_t temp = obj.Get('someProp').As<Napi::Number>().

How would I create a native (C++) value from a JS object property value?


Solution

  • I missed two things, which allow this to work:

    1. I was inconsistent with strings when using Get/Set. If Napi::Object::Set is used with single quotes, single quotes must be used with Napi::Object::Get; likewise for double quotes.
    2. Uint32Value() method needs to be used per the docs (I must have removed this in my tinkering), giving: uint32_t temp = obj.Get("someProp").As<Napi::Number>().Uint32Value();

    Fixing these issues provides the expected behavior and output.