Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

How to get a dojo handler to return value to calling function?

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.

1

1 vote



2 answers

Permanent link
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);
}

0 votes


Permanent link
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.

0 votes

Comments

Hello Mister Servizi,

It sure worth a try!
The downside on this code is, that it'll block the whole Process till the wished data (contributors) are retrieved.

But why keep it sequentially? Instead of A -> WAIT -> B
Why not going over a third method? A -> A-helper -> B
This way it would be non blocking code.

But if you just need some Field Values (That's why I'm guessing you want to use the return) It might work the way you suggested.

Another Idea could be to work with deferred.

getContributorData: function(userId) {
    var deferred = new dojo.Deferred();
    //Your code
    //Maybe its possible to directly return from the succees method since hitch keeps the same context.
    //return responseObj.elements[0];
    return deferred;
}

getContributor{
var
deferred = getContributorData(); deferred.then(function(value){ // Do something on success. }, function(error){ // Do something on failure. });
}

Your answer

Register or log in to post 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.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 10,927
× 34
× 1

Question asked: Jul 06 '16, 9:53 a.m.

Question was seen: 4,460 times

Last updated: Jul 25 '16, 2:03 a.m.

Confirmation Cancel Confirm