How to get a dojo handler to return value to calling function?
SEC Servizi (971●2●38●60)
| asked Jul 06 '16, 9:53 a.m.
edited Jul 06 '16, 10:07 a.m. by Ralph Schoon (63.5k●3●36●46)
We would be able to return a value from our function when this value has to come from an asynchronous service call:
getContributor: function(userId) { var contributor; var args = { searchField: "userId", searchTerm: userId }; var handler = { success: dojo.hitch(this, function(responseObj) { contributor = responseObj.elements[0]; }), error: function(errorObj) { console.log(errorObj.message); } }; var serviceResponseHandler = new com.ibm.team.repository.web.transport.ServiceResponseHandler(handler, "success", "error"); com.ibm.team.repository.web.client.internal.AdminClient.getContributors(args, serviceResponseHandler); return contributor; // undefined }
In this case, the returned value is "undefined" because the service call is not executed yet (i.e., it is an asynchronous call).
Any advice on how to make a sync call as in 'dojo.xhrGet({ ..., sync: true });'?
Thanks in advance.
|
2 answers
Hello Mister Servizi,
First you should be aware what asynchroneous means. As soon as you start an async process it's like a new Thread. Method A --> AsyncMethodA (Cant return to Method A because it isnt the same "process-Scope"[probably a wrong word]) So, if you wanna use async methods you'll have to adapt their behaviour. And thats, where the responseHandler comes into the play. All 3 calls will now land in the same method. How you will handle it, its your choice. Method A --> AsyncMethodA --> ResponseMethodA Method A --> AsyncMethodA --> ResponseMethodA Method A --> AsyncMethodA --> ResponseMethodA If you NEED a return value, use a synchroneous get. Problem: main: function(){ //test NEVER gets the value var test = this.getContributor("blabla"); } getContributor: function(userId) { var contributor; //1: NOT THE SAME CONTEXT //var contributor2 //2: Keep the same context var args = { searchField: "userId", searchTerm: userId }; //var self = this; //2: Here we give the method a possibility to keep the scope var handler = { success: dojo.hitch(this, function(responseObj) { contributor = responseObj.elements[0]; //1: AS THIS this.contributor = ... //1: This would be the same var as outside //self.contributor2 //2: This is now the same Object }), error: function(errorObj) { console.log(errorObj.message); } }; var serviceResponseHandler = new com.ibm.team.repository.web.transport.ServiceResponseHandler(handler, "success", "error"); com.ibm.team.repository.web.client.internal.AdminClient.getContributors(args, serviceResponseHandler); return contributor; // undefined //1: This stays undefined return contributor2 //2: Still not working, because it will not be setted when it's returned //2: You can check this if you'll add a wait/sleep method before the return } Solution: var transactionsInAction = null; var responseStorage = null; //A little idea how to handle async calls main: function(){ this.transactionsInAction = 0; this.responseStorage = []; this.getContributor("blabla1"); this.getContributor("blabla2"); this.getContributor("blabla3"); } dataResolved: function(contributor, transactionId){ this.responseArrays[transactionId] = contributor; //this.responseArrays.push(contributor); //Without transactionId this.transactionsInAction--; if(this.transactionsInAction < 1){ //No transactions in action this.doWhatYouWantOrNeed(); } } getContributor: function(userId) { var args = {}; //I keep it blank to save space //Better would be to use deferred but hitch works too, to keep the scope var handler = { success: dojo.hitch(this, function(responseObj) { var transactionId = this.transactionsInAction; //This could help to keep track which data are when loaded but not needed. this.dataResolved(responseObj.elements[0], transactionId); //This sends the response to the given method }), error: function(errorObj) { } }; this.transactionsInAction++; var serviceResponseHandler = new com.ibm.team.repository.web.transport.ServiceResponseHandler(handler, "success", "error"); com.ibm.team.repository.web.client.internal.AdminClient.getContributors(args, serviceResponseHandler); } |
Hello Jonas,
thank you for your answer. In your opinion, a naïve solution like this one below is not possibile?
getContributor: function(userId) { var contributor; var args = { ... }; success: dojo.hitch(this, function(responseObj) { contributor = responseObj.elements[0]; }), error: function(errorObj) { console.log(errorObj.message); } }; var serviceResponseHandler = new com.ibm.team.repository.web.transport.ServiceResponseHandler(handler, "success", "error"); com.ibm.team.repository.web.client.internal.AdminClient.getContributors(args, serviceResponseHandler); while (!contributor) { // wait until outer var get a value? } return contributor; }Thanks in advance.
Cheers.
Comments
Jonas Studer
commented Jul 25 '16, 2:02 a.m.
Hello Mister Servizi,
Jonas Studer
commented Jul 25 '16, 2:03 a.m.
getContributor{ |
Your answer
Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.