Tegud.NET

Blog

Sunday, 11 September 2011

Tuesday, 23 August 2011

This is the first of a three part blog series where I'm going to cover a feature of jQuery: deferreds. In Part One (here) we're going to cover the very basics, what they are and a simple example. In Part Two we'll have a much more useful example, before finally we'll cover the more advanced concepts around deferreds.

What are they?

jQuery deferreds were added during the overhaul of the AJAX module. Present in many other frameworks they provide a way of managing executing code upon completion of several asynchronous operations. As suggested by their inclusion during the overhaul of AJAX in jQuery, deferreds most obvious applications relate to AJAX.  Many examples focus on how deferreds can fire callbacks when several AJAX commands return.  In this and my next blog post I’m going to try and focus on showing first how deferreds work, and then to show a real life application (which does in fact use an AJAX request, but we’ll get to that).

Deferreds are a very powerful addition to jQuery and can help you tweak the execution to improve perceieved page load time to users, manage complex asynchronous activities and much more.  Rather than dive too much into the details of the methods available with deferreds, I’m going to try and show how it works at basic level in this post, provide a more practical case study in the 2nd post and then finally move onto a more in-depth look at the methods and properties available with deferreds in jQuery (in the future I also plan to do a blog post on deferreds in other frameworks).

First, a pointless example

Not the best advert, but this simple example doesn’t have much real life application. In this example we’re going to create three deferred objects and then use setTimeout() to resolve them at different times.  When each timeout elapses one of the LI elements is turned “on”. When all three deferreds have been resolved, the final div is turned “on” and it’s text set to done.

First thing we need to do is set up the three deferred objects. This is done simply enough:

var deferredA = $.Deferred(),
    deferredB = $.Deferred(),
    deferredC = $.Deferred();

Once we have the deferred object we can then set up how resolving them is handled. First thing we do is call the when method on the jQuery object.  This returns a chainable object, but it isn’t the usual jQuery object.  Another post will cover some of the other methods available , but for now the one we really care about is .then(). Then() accepts a callback as it’s parameter, once all the arguments to when() are resolved, this callback is fired.  Basically the logic you want executed when all deferred objects are resolved goes in then().  Putting this all together our deferred setup looks like this:

 $.when(deferredA,deferredB,deferredC)
      .then(function() {
          result.addClass('On').text('Done');
      });

All three deferred are passed to the $.when() function. Our “then” callback applies the class we want and sets the text to “Done” indicating all deferreds have been resolved.

Currently because we’re generating the deferreds manually we have to resolve them manually as well.  When using the deferreds returned from jQuery’s AJAX methods, they are resolved or rejected for us. We’ll cover how to handle errors later, for now we’ll stick to the basics.  In this example we’re going to resolve the deferreds using setTimeouts of various times.

setTimeout(function() {
    deferredA.resolve();
    ul.children(':eq(0)').addClass('On'); }, 500); 
}

setTimeout(function() {
    deferredB.resolve();
    ul.children(':eq(1)').addClass('On'); }, 3000); 
}

setTimeout(function() {
    deferredC.resolve();
    ul.children(':eq(2)').addClass('On'); }, 1500);
}

As each timeout fires, it resolves it’s deferred object, as soon as all the deferreds provided to the $.when() method are resolved, it fires the callback provided to .when().

I’ve posted a working example of this to jsbin.com so feel free to see it in action/tinker.

Show me something useful already

In the next part I'm going to explore a practical use for defers, one I've used at work, and plan on introducing to my site here as well.

Friday, 22 October 2010

I'm still awaiting my copy of Javascript Patterns, hopefully it'll arrive today so I have some weekend reading.  In the meantime I thought I would post about a technique of property/method access that not everyone will know about.

Accessing a method in javascript is not a complicated operation, usually you just do <object>.<method>().  Nothing hard there.  But this can sometimes lead to somewhat more verbose code that we'd like, for example say we wanted to add or remove a class using jQuery based on a boolean value.

if(myBool)
 	myElement.addClass("Active"); 
else
 	myElement.removeClass("Active");

Sure I can store the class name in a variable and not repeat that, but it'd still leave us with a multiline statement.  Fortunately we can compress this down to a single line of code.  In javascript we can access object property and methods by using array brackets but providing a string key for the property or method name, e.g. <object>["Method"](); Its important to note the method name is in a string, if you don't provide it as a string then it will not work as expected and probably error. Programmers of C# and similar languages will be familiar with this syntax for accessing Dictionaries and similar structures.  

So how can we use this to improve the code above?  Well as we're providing the method name as a string to the "[]", we can simply control what string is placed within it. 

myElement[(myBool ? "add" : "remove") + "Class"]("Active");

Now in the above statement we use a ternary statement to decide if we prefix "Class" with add or remove.  This determines in turn which property or method you call.  Some may argue (and indeed do at my work) that this has an impact on readability, but I personally think its worth the hit in terms of concise code.  Knowing about this method of accessing properties and methods can help you write code that takes advantage of this feature, leading to much less repetition of code. 

Monday, 14 June 2010

A discussion today led to me sending out an email to all the developers at work today, which given the amount of campaigning for jQuery I've done at the company, I had hoped would'nt have been necessary.  But it was.

Basically a co-worker had asked me for some assistance with some HTML/CSS.  Unfortunately this led to me looking at his code and discovering an abundance of javascript events specified directly within the HTML.

<div id="MyElement" onclick="javascript: myFunction();">Click Me!</div>

As I mention, we've adopted jQuery quite widely throughout our products, so I pointed out that it would be much easier for everyone to follow, and easier to take advantage of jQuery's special events and event delegation functions if the events were bound in the $(document).ready() function for that page.  What's more, we know the separating style and markup is important, keeping javascript and the markup separate is also important.  By keeping them apart it makes it easier to split the javascript off into a separate file (much easier to minify AND it's cached!).

So as I say this is just a quick blog post in case anyone else is unsure about where the best place to specify javascript events are.  In my opinion, not the HTML!

Friday, 04 June 2010

As part of what I aim to be a regular series I'm covering great jQuery articles and plugins I've seen over the previous week.  I aim to post this "around" Friday every week, this week may be a little light as I've only been keeping track of articles I've seen for the last few days. 

As I say, next weeks should have a little more to it. I aim to be a lot more active on this site this year and going forwards, next stage is to implement the article system to display more in-depth articles.  In the mean time I shall endeavour to keep blogging.

Wednesday, 20 May 2009

Downloaded the beta of Visual Studio 2010 today.  I was expecting WPF to have worked its way in deeper than it has done, currently its only in the editor, but the changes are very nice.  Oddly enough I espcially like the text selection effect, as well as the scaling and general look and feel.  In addition the changes of Intellisense now filtering is very nice.

Havent had much chance to try out the .NET 4.0 additions, I am quite looking forward to playing around with the new dynamic types.  One change that caught my eye on the Web Forms was the ClientID addition, with the added ability to control the client id of server controls directly it'll bypass the need to "tell" javascript what server control IDs are.

Will post again once I've had some more time with the new changes.

Friday, 03 April 2009

Well, did it again, still working on the RSS Feed widget thing which you can now see on the right.  Its still very early on, but it does do things!  Basically my long term aim for it to tell you if theres new RSS items and also allow it to be configurable per user, with a set of default ones for users who arent logged in. I dont plan for it to update automatically, but it does have a refresh button.

As I say, its REALLY early on, much like the majority of this site its a little rough at the moment, but its been a good test bed for some more JQuery fun.  As you may have noticed from the menu system across the site I'm kinda liking the slidey menu thing at the moment and thats been once more used in the RSS Feed display.  Basically if you click on the title of the RSS Feed (with the zoom icon) it'll bring up a full list from the RSS feed, the top one item from the feed is displayed immediatly below.  Its all done via JQuery AJAX, however instead of pulling the feed direct off the sites, I used an ASP.NET page local to this server to go get them, then the JQuery to process that, means I wont have any Javascript permissions issues...

Wednesday, 01 April 2009

Opps, it would appear to be 1am, and on a school night no less. I may have got slightly carried away with the JQuery RSS feed reader I'm writing for the front page. I'm taking a break from the photo gallery to work on something else. I reached the stage where I have to write the interface for loading photos into the database, which is less than fun, but needs doing. I need to work out how to import photos from a folder into the DB with minimal effort.  I am thinking of also including some kind of location based system accross the site soonish as well.

The site is now technically live, but really all that means is that it can be accessed from the web, I'll be surprised if it gets any hits currently.  I plan on going through and working out the SEO in a week or so, once I've completed the Gallery and the RSS thing. If you do stumble upon here feel free to say hi.

Wednesday, 25 March 2009

Been playing around with JQuery alot lately, really enjoying it. It takes away alot of the pain of doing things in javascript. I was talking to some guys at work today about what it can do, them being difficult were mainly pointing out you could do it all in javascript anyway, which is true, but its hardly going to do something you cant do in javascript.  But what it does do is enable you to do it much easier.  Animations for example, you could use timeouts to move things gradually, or you can use $("#someId").animate();, which is obviously way easier.  And with more people using JQuery instead of writing their own stuff, code becomes more readable and maintainable.

Alot of this website has been an experiment for me in using JQuery, so somethings could be done better, but its all part of the learning process for me.  The only real area I havent explored properly is the AJAX functions, but apart from that I've been using the other parts quite alot.  The photo gallery has some of the more advanced JQuery on the website, it handles basically all of it.  I combined that with a ASP.net image resizer and the gallery slide view was basically done. Next thing I plan on doing is the list view, which will show one gallery at a time and allow the user to scroll through it.  It will most likely also use lots of JQuery.

Saturday, 07 March 2009

This is a problem I encountered whilst working on a configuration XSD at work, I wanted to have a node that had content, with an enforced type along with attributes.  An example of the XML I wanted to allow is below.

<Quotes>
    <Quote author="George W. Bush">Rarely is the questioned asked: Is our children learning?</Quote>
</Quotes>

To specify a type for the node contents as well as some attributes, we need to use a type extension, specifying the type we want for the content as the base type.   This is shown below.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Quotes">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="Quote">
            <xs:complexType>
              <xs:simpleContent>
                <xs:extension base="xs:string">
                  <xs:attribute name="author" type="xs:string" />
                </xs:extension>
              </xs:simpleContent>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:schema>

The XSD above will permit the XML we want, and allow content and attributes on the same node.  I'll probably do some more stuff on XSDs in the near future.