Skip to content

Example: DynamicObject

Craig Minihan edited this page Apr 23, 2015 · 14 revisions

DynamicObject implements a truly dynamic object instance which you can expose to JavaScript. The properties of the object do not need to be known in advance. For example:

   alert(msg.text);

If the msg object was a libjsapi DynamicObject then the reference to the text field would be routed to the GetCallback supplied in the object Create() call. In the get call you can return any value you like to SpiderMonkey including undefined, null or the classic "hello world".

The following example should field values being resolved by a std::unordered_map, any fields not found return undefined as you would expect from a real JavaScript object.

#include <iostream>
#include <vector>
#include <unordered_map>

#include "libjsapi.h"

int main() {
    std::unordered_map<std::string, std::string> data = {
        { "hello", "world" }, { "lorem", "ipsum" },
        { "foo", "bar" } };

    rs::jsapi::Runtime rt;

    // create a dynamic object which returns a string from the map
    rs::jsapi::Value obj(rt);
    rs::jsapi::DynamicObject::Create(rt,
        [&](const char* name, rs::jsapi::Value& value) {
            auto result = data.find(name);
            if (result != data.cend()) {
                value.set(result->second);
            } else {
                value.setUndefined();
            }
            return true;
        },
        nullptr,
        nullptr,
        nullptr,
        obj);

    // create a function which returns the value of the field 'n'
    // on the passed object
    rt.Evaluate("var myfunc=function(o, n){return o[n];};");

    rs::jsapi::FunctionArguments args(rt);
    args.Append(obj);
    args.Append("hello");

    // invoke the function and get the value of the field 'hello'
    rs::jsapi::Value result(rt);
    rt.Call("myfunc", args, result);
    std::cout << result << std::endl;

    // invoke the function and get the value of the field 'lorem'
    args[1] = rs::jsapi::Value(rt, "lorem");
    rt.Call("myfunc", args, result);
    std::cout << result << std::endl;

    // invoke the function and get the value of the field 'foo'
    args[1] = rs::jsapi::Value(rt, "foo");
    rt.Call("myfunc", args, result);
    std::cout << result << std::endl;

    // invoke the function and get the value of the field 'xyz'
    args[1] = rs::jsapi::Value(rt, "xyz");
    rt.Call("myfunc", args, result);
    std::cout << result << std::endl;

    return 0;
}

Running the example yields the following output on the console:

world
ipsum
bar
undefined
Clone this wiki locally