Question

I'm developing an application with HTML service and I want to use the Module Pattern.

I don't know why the functions inside the function are losing the reference to the object. I don't know if this is a google apps script server call related problem or a general javascript one.

Could someone help me to find the problem? Here is the code.

var Handshake = (function () {

var self = this;
var contacts; 

    google.script.run.withSuccessHandler(parse).withUserObject(this).withFailureHandler(onFailure).getContacts();
    console.log("JUST CALLED GET CONTACTS");


function parse (JSONstring,parent)
{
   parent.contacts = JSON.parse(JSONstring);
   console.log ("Parsed info "+JSON.stringify(parent));
}


return {

    contacts : contacts
}

}());

Seems that Guillaume found the problem, but I don't understand why the object behaves like this.

If you make it even more generic, and I launch it from a commandLine, this is what I get:

var Handshake = (function () {

var self = this,contacts,parse; 

parse = function (JSONstring,parent)
{
   console.log(this);
   this.contacts = JSON.parse(JSONstring);
   console.log ("Parsed info "+JSON.stringify(this));
};

console.log("Undefined handshake?"+this);
console.log("JUST CALLED GET CONTACTS");

return {

    contacts : contacts, parse:parse
};

}());

Output:

Undefined handshake?[object Window] 

EDIT Finally I found the problem. As Guillaume pointed, this was pointing to the window object. I think I should check again how object works. Moving the google script call into a function fixed this problem.

Here is the function:

init = function() {

console.log("Undefined handshake?"+JSON.stringify(this));
google.script.run.withSuccessHandler(parse).withUserObject(this).withFailureHandler(onFailure).getContacts();
console.log("JUST CALLED GET CONTACTS");

}; 

If someone would like to explain me why this is the correct approach I will be grateful.

Was it helpful?

Solution

I do not believe you lose the object ref, which seems (without knowing more about the call context ) to be root windows object when calling google.script.

Have you tried to use your function as :

var parent = .. ; // myContextObject which will be used as 'this'
var HandshakeFn = function(){..};
var Handshake = HandshakeFn.call(parent);

To clarify the answer, every function call in javascript is owned by an object (the context), which is default as window (the root). When you call the Handshake function as you have done using

Handshake = (function(){...})();

the context 'this' is the object from where it has been called. Because you call your function directly from the root, any reference to 'this' in the function will return a ref to the window.

To avoid this behavior, you may explicitly set the calling context using

HandshakeFn.call(myobject);

With that, 'this' will refer to myobject instead of window. And when you set the user object to googlescript it will return the proper object in the second 'parent" parameters.

What i suggest here is to avoid dealing with the context and second parameter with google script

var Handshake = (function () {

var self = {}; // you need to explicitely create an object here !

google.script.run.withSuccessHandler(parse).withFailureHandler(onFailure).getContacts();
console.log("JUST CALLED GET CONTACTS");


function parse (JSONstring)
{
   self.contacts = JSON.parse(JSONstring);
   console.log ("Parsed info "+JSON.stringify(self));
}

return self;

}());

Do not forget to vote if you find this useful.

P.S. : Sorry for my poor English, it is not my native language.

regards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top