I recently did a post where I discovered a very cool trick done by the xamarin folks that had to do with executing an anonymous method in the call parameter list of a c# function call. Basically, the idea was that you call some method to do something, then at the end of that method instead of immediately returning, you execute the dynamic function that was passed in. That way, you can avoid all the gu involved with creating call back methods. You can read about it here: https://peterkellner.net/2012/08/30/in-c-passing-delegate-as-parameter-then-executing-on-return/
So, as many of you know. I’m pretty good at getting c# to do what I want and finding tips like this is always a big surprise and fun to share. So, now I’m trying to finish up my first Windows 8 HTML5/JavaScript app and I run into exactly same problem. Since one of my readers pointed out that this technique is very common in JavaScript I figure I could try it here. I did, it did and I’m a happy camper.
So basically, I created a namespace and a very nice function in that name space to do an XHR request using promises and then on completion return. The problem is, on completion I want the caller to do something. So, let me give a concrete example of what my code kind of looks like.
Here is the definition of my function that does the xhr request.
(function () { "use strict"; WinJS.Namespace.define("AE.Functions", { fetchEmail: function (nav, searchString, action) { var that = this; WinJS.xhr({ type: "post", url: AE.Constants.baseUrl + "EmailDetail/GetPersonsWithEmailByEmailAccount", headers: { "Content-type": "application/x-www-form-urlencoded" }, data: formParams, scope: that }).then(function (xhr) {AE.Logging.LogFetchEmail(<span class="str">"fetchEmail:done"</span>); action(); }); } });
})();
Notice the third parameter of the function called “action”. Also notice after the AE.Logging. call that action is called. That means, when the xhr request finishes, the dynamic function in the caller is executed.
Something like this (ok, exactly like this):
function fetchEmail() { if (appView.value != appViewState.snapped) { AE.Functions.fetchEmail(nav, AE.Constants.Utils.emailSearchString,function () { var x = document.getElementById('progresscontrolid'); x.style.visibility = "hidden"; }); } }
What I’m actually doing is turning off a progress control when the xhr request is finished.
That’s it! Same trick, different language.
HTH’s