2

I am trying to verify that an object passed to a node addon is of the correct type before I unwrap it and start to use it. Here's the solution that I've cobbled together from looking at various sources on the web.

Persistent data:

Nan::Persistent<v8::Function> Event::constructor;
Nan::Persistent<v8::FunctionTemplate> Event::tpl;

The Init function:

void Event::Init(v8::Local<v8::Object> exports) {
    Nan::HandleScope scope;

    // Prepare constructor template
    v8::Local<v8::FunctionTemplate> ctor = Nan::New<v8::FunctionTemplate>(Event::New);
    ctor->InstanceTemplate()->SetInternalFieldCount(1);
    ctor->SetClassName(Nan::New("Event").ToLocalChecked());

    // create a template for checking instances
    Local<FunctionTemplate> localTemplate = Nan::New<FunctionTemplate>(Event::New);
    localTemplate->SetClassName(Nan::New("Event").ToLocalChecked());
    tpl.Reset(localTemplate);

    // Statics
    Nan::SetMethod(ctor, "x", Event::X);

    // Prototype
    Nan::SetPrototypeMethod(ctor, "addInfo", Event::addInfo);
    Nan::SetPrototypeMethod(ctor, "toString", Event::toString);

    constructor.Reset(ctor->GetFunction());
    Nan::Set(exports, Nan::New("Event").ToLocalChecked(), ctor->GetFunction());
}

And where I attempt to use it:

    if (Nan::New(tpl)->HasInstance(info[0])) {
        message = "it is an Event instance";
    }

The problem is that the HasInstance() never returns true.

The JavaScript code is basically

let e = new Event()
fn(e)     // where fn performs the HasInstance() test.
bmacnaughton
  • 4,950
  • 3
  • 27
  • 36

1 Answers1

1

There is no need to make a second FunctionTemplate. The one you've set on the exports (ctor) is the one that gets used when you call new Event() in JS, while the second one (localTemplate) gets saved to Event::tpl and is the one from which the HasInstance() call gets made. They're different FunctionTemplates, so the HasInstance() call returns false.

Instead of this:

...
Local<FunctionTemplate> localTemplate = Nan::New<FunctionTemplate>(Event::New);
localTemplate->SetClassName(Nan::New("Event").ToLocalChecked());
tpl.Reset(localTemplate);
...

just try this:

...
tpl.Reset(ctor);
...
tgvarik
  • 56
  • 3
  • 1
    I'd solved the problem as you suggested but forgot I'd asked the question. There's not much Nan/NAPI focus here. But your answer is spot on and helpful! Thanks. – bmacnaughton Nov 07 '18 at 00:56