[Dojo-interest] Error in accessing class variables

0 views
Skip to first unread message

abhi

unread,
Nov 14, 2009, 4:51:11 AM11/14/09
to dojo-i...@mail.dojotoolkit.org
I was developing my app using simple functions. As my code started to
grow, I decided to encapsulae them into Classes. Here is one such snippet:


dojo.declare("userView", null, {
constructor: function(pageUrl, leafUrl) {
this.pageUrl = pageUrl;
this.leafUrl = leafUrl;
this.pageGet = dojo.xhrGet({ url: this.pageUrl, handleAs:
"text", content: {method: 'read'}});
this.leafGet = dojo.xhrGet({ url: this.leafUrl, handleAs:
"text", content: {method: 'read'}})
},

publish: function(){
dojo.addClass("menu_1", "dojoxGridRowSelected");
var userfetchArgs = {
sort: [{attribute:"cn", descending:true}],
onBegin: showUsersLoading,
onComplete: this._getUserGrid,
onError: this._loadError,
};
userfetch = userJsonStore.fetch(userfetchArgs);
},

_getUserGrid: function(){
console.log("Loading Page");
console.log(this.pageGet);
this.pageGet.addCallback(function(response) {
this._setUserGrid(response);return response});
console.log("Loading Leaf ");
this.leafGet.addCallback(function(response) {
this._setUserForm(response);return response});
},

_setUserGrid: function(response){
[...]
},

_createUserGrid: function(){
[...]
},

_setUserForm: function(response){
[...]
},

_loadError: function(response, ioArgs){
[...]
},


});

I create objects using the new keyword and call the publish method.
OnComplete fires the _getUserGrid method but nothing happens. Firebug
logs this:

Loading Page
undefined
undefined

Can some one tell me why this.pageGet returns an undefined and how I
should be doing this in dojo ?

Regards,
Abhi
_______________________________________________
FAQ: http://dojotoolkit.org/support/faq
Book: http://docs.dojocampus.org
Dojo-i...@mail.dojotoolkit.org
http://mail.dojotoolkit.org/mailman/listinfo/dojo-interest

asheikh

unread,
Nov 14, 2009, 7:50:59 AM11/14/09
to dojo-i...@mail.dojotoolkit.org
Hi,

I don't know that much about dojo and javascript, but I think it has to do with the object scope.

try this...

        publish: function(){
          var _self = this;

          dojo.addClass("menu_1", "dojoxGridRowSelected");
          var userfetchArgs = {
              sort: [{attribute:"cn", descending:true}],
              onBegin: showUsersLoading,
              onComplete: _self._getUserGrid,
              onError: _self._loadError,
          };
          userfetch = userJsonStore.fetch(
userfetchArgs);
          },

Phil Bowles

unread,
Nov 14, 2009, 9:16:53 AM11/14/09
to dojo-i...@mail.dojotoolkit.org
You have fallen foul of asynchronous programming...

When your routine is executed, it is no longer in the context of the object
in which it is declared, but in the context of what fires the event...
userJsonStore in this case.

You need to use dojo.hitch to "tie" the context at the time of creation to
that which will be used when it is actually executed

e.g. onComplete: dojo.hitch(this,"_getUserGrid");

you will need to do that for any function that will be called
asynchronously, ie when some external event occurs (such as fetch completion
etc)

abhi

unread,
Nov 15, 2009, 9:05:07 AM11/15/09
to dojo-i...@mail.dojotoolkit.org
On Saturday 14 November 2009 07:46 PM, Phil Bowles wrote:
> You have fallen foul of asynchronous programming...
>
> When your routine is executed, it is no longer in the context of the object
> in which it is declared, but in the context of what fires the event...
> userJsonStore in this case.
>
> You need to use dojo.hitch to "tie" the context at the time of creation to
> that which will be used when it is actually executed
>
> e.g. onComplete: dojo.hitch(this,"_getUserGrid");
>
> you will need to do that for any function that will be called
> asynchronously, ie when some external event occurs (such as fetch completion
> etc)
>
Thanks phil, After your email, I did some more reading of hitch and its
cousins. I also found some interesting links:
http://www.dojotoolkit.org/2008/12/11/top-10-things-you-should-know-about-dojo

I did changes to my code to run everything in the scope. For e.g:

this.pageGet.addCallback(dojo.hitch(this, this._setUserGrid));

instead of

this.pageGet.addCallback(function(response) {
this._setUserGrid(response);return response});

I do have one doubt about hitch?
How does hitch know that it has to pass "response" to the hitched
function and
that it has to return the response after the callback is called. i.e
when I add more callbacks to the my deferred object,
they all receive the xhrGet response.

I had initially tried this :

this.pageGet.addCallback(function(response) {
dojo.hitch(this, _setUserGrid, response);return response});

This did not call the method as hitch returns a function if I am correct.


Thanks for clarifying my doubts,

Ed Schiebel

unread,
Nov 15, 2009, 2:04:14 PM11/15/09
to dojo-i...@mail.dojotoolkit.org
dojo.hitch doesn't call your function, it just creates a closure around your function so 'this' has the value you expect when your function is called. You could get similar results with code somethig like
var me = this;
this.pageGet.addCallback(this._setUserGrid);

then in _setUserGrid, refer to "me" instead of "this". dojo.hitch makes this much cleaner.
--ed


Subject: Re: [Dojo-interest] Error in accessing class variables
To: dojo-i...@mail.dojotoolkit.org
Message-ID: <4B000A9...@littlewiki.in>
Content-Type: text/plain; charset=UTF-8; format=flowed
Reply all
Reply to author
Forward
0 new messages