Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v8 c++ - how to get object key values provided as arguments

I'm passing a js object to my function like this

myFunc.do({'1':2});

I want to std::cout those key values pairs from my object in c++

Here is what I have

Handle<Object> object = Handle<Object>::Cast(args[i]);
Local<Array> objArray = object->GetPropertyNames();

 for(uint o=0; o < objArray->Length(); o++) {
   Local<Value> val = objArray->Get(o);
   v8::String::Utf8Value str(val->ToString());
   std::string foo = std::string(*str);    
   std::cout << "val is= " << foo;
 }
return;

I'm doing wrong with object->GetPropertyNames();, because it does not gets me the passed values

UPDATE Here is another useless try

Local<Context> context = isolate->GetCurrentContext();
Local<Object> object = Local<Object>::Cast(args[i]);
Local<Array> props;
if (!object->GetOwnPropertyNames(context).ToLocal(&props)) {
  std::cout << "Error";
  return;
}

for (uint32_t p = 0; p < props->Length(); ++p) {
  Local<Value> name;
  Local<Value> property_value;
  props->Get(context, p).ToLocal(&name);
  v8::String::Utf8Value str(name->ToString());
  std::string foo = std::string(*str);    
  std::cout << "val is= " << foo; // outputs 0
}

thanks for help

like image 836
xhallix Avatar asked Nov 10 '16 17:11

xhallix


People also ask

How do I get all the values of an object?

values() Method: The Object. values() method is used to return an array of the object's own enumerable property values. The array can be looped using a for-loop to get all the values of the object.

How do you find the key of an object?

Use object. keys(objectName) method to get access to all the keys of object. Now, we can use indexing like Object. keys(objectName)[0] to get the key of first element of object.


2 Answers

A verifiable example, tested on node 7, should work on 6 and 4 too, for other versions of node you would probably need nan:

// logger.cc
#include <string>
#include <iostream>
#include <node.h>

namespace demo {

using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;
using v8::Array;
using v8::Exception;

// Logging function for objects
void Log(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if(args.Length() < 1 || !args[0]->IsObject()) {
    isolate->ThrowException(Exception::TypeError(
    String::NewFromUtf8(isolate, "Error: One object expected")));
    return;
  }

  Local<Context> context = isolate->GetCurrentContext();
  Local<Object> obj = args[0]->ToObject(context).ToLocalChecked();
  Local<Array> props = obj->GetOwnPropertyNames(context).ToLocalChecked();

  for(int i = 0, l = props->Length(); i < l; i++) {
    Local<Value> localKey = props->Get(i);
    Local<Value> localVal = obj->Get(context, localKey).ToLocalChecked();
    std::string key = *String::Utf8Value(localKey);
    std::string val = *String::Utf8Value(localVal);
    std::cout << key << ":" << val << std::endl;
  }
}

void CreateFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, Log);
  Local<Function> fn = tpl->GetFunction();

  // omit this to make it anonymous
  fn->SetName(String::NewFromUtf8(isolate, "loggerFunction"));

  args.GetReturnValue().Set(fn);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateFunction);
}

NODE_MODULE(logger, Init)

}  // namespace demo

Bindings:

{
  "targets": [
    {
      "target_name": "logger",
      "sources": [
        "logger.cc"
      ]
    }
  ]
}

Tester:

const logger = require('./build/Release/logger');
var log = logger();

log({'Cave' :'Johnson'});
log({'1':2});
log({a: 1});

Output:

Cave:Johnson
1:2
a:1
like image 83
Marcs Avatar answered Sep 19 '22 21:09

Marcs


Here is my implementation:

void do_handler(const FunctionCallbackInfo<Value>& args)
{
  Isolate* isolate = args.GetIsolate();
  if (args.Length() < 1 && !args[0]->IsObject()) {
    isolate->ThrowException(Exception::TypeError(
      String::NewFromUtf8(isolate, "Wrong arguments: object expected")));
    return;
  }
  auto obj = args[0]->ToObject(isolate);
  Local<Array> props = obj->GetOwnPropertyNames();
  for (uint32_t i = 0; i < props->Length(); ++i) {
    const Local<Value> key_local = props->Get(i);
    const Local<Value> val_local = obj->Get(key_local);
    std::string key = *String::Utf8Value(key_local);
    std::string val = *String::Utf8Value(val_local);
    std::cout << "\"" << key << "\"" << ": \"" << val << "\"" << std::endl;
  }
}
like image 25
Konstantin Emelyanov Avatar answered Sep 22 '22 21:09

Konstantin Emelyanov