Bind class instance function to v8::FunctionTemplate - javascript

I'm fairly new to C++ and v8 in general, and I wanted to build a native node.js addon, but now I'm stuck on something quite simple IMO, but I can't figure out what the issue is, the error message
C:\Path\To\Project\File.cpp(50): error C2664: 'v8::Local<v8::FunctionTemplate> v8::FunctionTemplate::New(v8::Isolate *,v8::FunctionCallback,v8::Local<v8::Value>,v8::Local<v8::Signature>,int,v8::ConstructorBehavior,v8::SideEffectType)': cannot convert argument 2 from 'v8::Local<v8::Value> (__cdecl *)(const v8::FunctionCallbackInfo<v8::Value> &)' to 'v8::FunctionCallback' [C:\Path\To\Project\build\node_gui.vcxproj]
is not that helpful.
I've got the following code,
v8::Local <v8::Object> Window::GetFunctions() {
v8::Local <v8::Object> DrawFunctions = v8::Object::New(isolate);
v8::Local <v8::FunctionTemplate> bgfnc = v8::FunctionTemplate::New(isolate, &Window::BackgroundCB);
DrawFunctions->Set(v8::String::NewFromUtf8(isolate, "background"), bgfnc);
return DrawFunctions;
}
void Window::Background(const v8::FunctionCallbackInfo <v8::Value> &args) {
v8::Isolate *isolate = args.GetIsolate();
renderer->Background(args[0]->NumberValue(), args[1]->NumberValue(), args[2]->NumberValue());
}
v8::Handle <v8::Value> BackgroundCB(const v8::FunctionCallbackInfo <v8::Value> &args) {
return ((Window*)v8::External::Cast(*(args.Data())->Value())->Background());
}
I want to create an object that contains a list of functions, the functions' callbacks would be member functions of the Window class. I know this has been asked before here, which worked once using a non-member function but otherwise not.
Thanks
Sidenote: I've looked far and wide for v8 docs that are suitable for beginners, the nodesource ones don't explain what the parameters mean or rarely give a thorough example of how to use the function / class, if anyone knows some better docs, that would be great, thank you.

Thanks to the gracious and prompt help of the community, I was able to quickly and effortlessly resolve this issue. Turns out, when writing NodeJS addons, it's a good idea to use NodeJS's own N-API, as the documentation is simpler, clearer, and most importantly, existant.

Related

Is calling a property's method from another method of the same object in this manner ok?

Can someone help me understand why the code below works and if this is an acceptable pattern to use?
Without getting into it too much I have a basic state machine functionality inside an object called states in a simple browser game I am making and I able to trigger event transitions by calling states.event('someEvent') from within the states object itself. For instance if the update method of a given state, say states.someState.actions.onUpdate() is running it can call states.event('someNewEvent'). Doing it this way is not something I need to do, I did it accidentally but I was very confused by the fact that it worked. So the code below is that logic/functionality which I don't understand reduced down to a simple example.
I can't seen to find any information that would explain this type of pattern.
Everywhere online would seem to suggest that I write "this.printText()" instead of "myObj.printText()" but it only prints when I do it the way I have below.
This seems like it might be bad practice, at the very least it would be because I don't understand quite why it works... Any help would be appreciated. I struggle a lot with javascript coming from C# in unity game engine.
let myObj = {
printText: function() {
console.log('I thought this would not print');
},
myProperty: {
toPrint: function () {
myObj.printText();
}
}
}
myObj.myProperty.toPrint();

Temperamental `nestRemoting()` sometimes can't find relation

I'm implementing the (not so well documented) loopback method nestRemoting() as follows:
module.exports = function(MyModel) {
MyModel.on('attached', function() {
MyModel.nestRemoting('relationName');
});
}
However this seems to be very temperamental. Sometimes it works, but most of the time I get:
Relation `relationName` does not exist for model `MyModel`
at ....stacktrace....
.....
Does anyone know why this error might be occurring?
So, I found the solution only moments after posting - you can only do nestRemoting after the model has been attatched... not attached. Simple spelling mistake can fix all woes.
Perhaps this post will help someone else trying to nest endpoints.

visual studio code JavaScript code completion

Trying to use the Microsoft VS code to develop node.js app.
I'm starting with deciding if it worth the effort of learning this new IDE (new for me). so for now i am not asking about node.js completion rather my own objects.
I read about adding code completion for different packages, but my problem is much more basic.
I can't get code completion for my own JS objects.
Lets say i have this simple object:
function User() {
this.name = '';
}
var me = new User();
me. ????
when trying to get to the name property of User after instantiating it there is no code completion for the object properties.
It is something i am doing wrong or is it a basic problem?
to be clear. i am getting code completion for the node.js classes built in JS objects.
It has some really great things built in it but i can't find a solution for this basic problem.
10x
It seems that VSCode does not detect this pattern. If you would use a ES6 class:
class User {
constructor() {
this.name = '';
}
}
var me = new User();
me. // now proposes name

Cannot wrap my head around Immediately Invoking Anonymous Functions in Javascript

I have been studying framework development for a few weeks, and I ran across what is highly suggested and pressured in the world of lib development, Immediately-invoking Anonymous Functions.
I never can get it to work, and I have failed to find a resource that explains in-detail the use and logic behind it.
Here's what I know so far:
It's immediately invoking - It runs everything anonymously, immediately.
It's anonymous - It does not carry a name therefore the code inside of it is not "reachable" by exterior code.
You can pass global window, object and undefined parameters - That's about all I know on that, but do not understand them completely.
I am looking not only for a detailed resource, but one that explains the logic behind it. Because I find it very illogical.
Here's what I have:
(function( window, document, undefined ) {
window.myThingy = myThingy;
var myThingy = function() {
};
myThingy.prototype = {
constructor: myThingy,
create: function( elementToBeCreated ) {
return document.createElement( elementToBeCreated );
}
};
})( window, document );
Then,
myThingy().create("div");
But it is still saying myThingy() [object] is not a function.
What am I doing wrong? Why should I use immediately-invoking functions and not just create a global myThingy = function() object? Why do I have to use window?
I know there are several resources on the net about this, but I can't understand any of it. Some of them go half-way into detail, some of them try to go into detail, but fail to explain the critical stuff. Why is this so stressed when developing a framework?
Don't worry, I'm not trying to "re-invent the wheel", but I am trying, however, to actually learn JavaScript, not just the pre-packaged stuff.
A good answer should contain:
A good resource where it explains the logic behind immediately invoking anonymous functions
An insight to that link
What I am doing wrong with the code I provided
First off, you have not yet defined your function when you try to assign it to the global object so it is undefined:
window.myThingy = myThingy;
console.log(myThingy);//undefined
You need to do the assignment after myThingy is defined:
(function( window, document, undefined ) {
var myThingy = function() {
};
myThingy.prototype = {
constructor: myThingy,
create: function( elementToBeCreated ) {
return document.createElement( elementToBeCreated );
}
};
window.myThingy = myThingy;
})( window, document );
Okay, next, you cannot use
myThingy.create("div");
because myThingy is a function and not an object. Function objects are created when the new keyword is issued to a function. You can make this change to convert your function into a function object:
window.myThingy = new myThingy();//create a function object
This pattern is not how all frameworks are implemented, but similar. Sometimes there is more abstraction. However, making these changes will allow your approach to work.
Here is a demo of your code: http://jsfiddle.net/ZjRJW/
Links
Here are some of my favorites:
http://ejohn.org/blog/simple-class-instantiation/
http://ejohn.org/apps/learn/
http://ejohn.org/blog/simple-javascript-inheritance/
http://jibbering.com/faq/notes/closures/
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model
http://javascript.crockford.com/prototypal.html
If you want to learn about JS design patterns, I highly recommend Addy Osmani's books/articles. He keeps things very simple and usually supplies quite a bit of example code to help you understand. As far as your code and implementing a design pattern is concerned, it depends on what you want your code to do, and how you want your code/objects to behave. Understanding your requirements/goals are very important before you start coding so you don't get lost in a spaghetti of patterns that really aren't solving a specific problem.
In some cases, implementing a pattern intended for a complex, large application is simply overkill.
Since someone else already correctly pointed out the issues with your code, I'll just leave it there.

Minimalistic example of IPython kernel javascript bi-directional communication

My goal is to write an interactive variable viewer for IPython, i.e. which allows one to see, say nested dicts/lists as a tree, and drill down (a bit like the console.log in Javascript).
I spent a lot of time trying to extract minimalistic code out of the directview example in IPython but still can't get my head around how it all works. My Python's ok but my jQuery experience is quite limited.
So I got to stripping down directview.js to the following
container.show();
var widget = $('<div/>')
element.append(widget);
var output = $('<div></div>');
$(widget).append(output)
var output_area = new IPython.OutputArea(output, false);
var callbacks = { 'output': $.proxy(output_area.handle_output, output_area) };
var code = 'print 1+1'
var msg_id = IPython.notebook.kernel.execute(code, callbacks, {silent: false});
This works when I load the directview.ipynb. However I am still not clear how to make it completely standalone (i.e. not require the directview.py, and pass another callback than the standard handle_output of IPython.OutputArea). One of the issues is the container.show() which fails when called in a standalone way.
I am lost on several aspects:
Why is there an element.append(widget) and then $(widget).append(output)? Also why is there also a need to create an Ipython.OutputArea. Isn't there a way to just create a <div id=my_output_area>blah</div> and then have the output callback fill it with the relevant data?
What's the whole .proxy thing about? I would like to create my own callback for output but when I do that and console.log() the arguments passed to the callback, they're undefined or just useless.
I appreciate that the authors of the IPython notebook have done an incredible job creating such a beautiful front-end using jQuery/websockets, and that creating developer documentation that allows beginners like me to tweak with it is asking much, but if anyone can lend a hand that would be great!
I can answer to your second question. The fact is when JavaScript calls your callback, it makes it so without specifying the context, i.e. without setting this (Pythonistas call it self). But it's possible to bound a function to this via $.proxy, which you saw in:
var callbacks = { 'output': $.proxy(output_area.handle_output, output_area) };

Categories