Calling jQuery's Data() Method Without Arguments

Posted February 1, 2010 at 10:10 AM by Ben Nadel

Tags: Javascript / DHTML

With jQuery 1.4, I was very happy to see that they finally gave us the ability to invoke the data() method without arguments. Calling the data() method in this way returns an object containing all of the keys stored using the data() method on this object. When I was working on my jQuery image zoom experiment, I made heavy use of this feature to store data points without having to call the data() method each end every time. I was able to do this because the object returned by the data() method is the actual data cache object - passed by reference - and not a copy of it. As such, once you have the data cache, direct changes to it will be reflected in all subsequent calls to the data() method on that object.

 
 
 
 
 
 
 
 
 
 

Of course, it never is quite that straightforward. jQuery's data() method only returns the object's data cache if the cache exists; and, the cache only exists if a value is currently being stored in it. If no keys have been stored in the cache, or all the keys have been deleted (using removeData()), then the data() method will return null, not an empty cache object. I assume that they are doing this for optimization purposes, but there's something I don't like about it; it makes the data() method's behavior dependent on the previous uses of data() and this difference in data() potential just seems dangerous.

To make the data() method's behavior uniform, we can override the original data() method to apply some intercepting business logic. In the following demo, you'll see that I wrap the original data method using my own data method (is that AOP - Aspect Oriented Programming??). My version of the data method then applies the call to the original data method and, if the data method returns a null cache object, I store a data point in the elements data cache before returning the data cache. While this definitely feels sloppy in and of itself, storing this bunk name/value pair forces the data cache to become sticky.

  • <!DOCTYPE HTML>
  • <html>
  • <head>
  • <title>Calling jQuery's Data() Method Without Arguments</title>
  • <script type="text/javascript" src="jquery-1.4.js"></script>
  • <script type="text/javascript">
  •  
  • // Here, we want to override the data() method so that
  • // non-argument calls to it will always return the data
  • // store object.
  • (function( $ ){
  •  
  • // Get a reference to the original data method.
  • var originalData = jQuery.fn.data;
  •  
  • // Override the data method to ensure that the data
  • // store is always returned.
  • jQuery.fn.data = function(){
  •  
  • // Check to see if there are any arguments passed
  • // in. This is the only case we care about.
  • if (!arguments.length){
  •  
  • // Get the storage object.
  • var dataStore = originalData.apply( this );
  •  
  • // Check to see if the dataStore exists. If
  • // it does, then just return it; otherwise,
  • // we'll have to create one.
  • if (dataStore){
  •  
  • // Return current store.
  • return( dataStore );
  •  
  • }
  •  
  • // If we made it this far, then the data store
  • // returned was null which means it has never
  • // be accessed before. To create it, we
  • // actually have to set a key in it. We also
  • // have to keep the key in there, otherwise
  • // jQuery will try to delete the data store.
  • originalData.apply( this, [ "_", "_" ] );
  •  
  • // Now that the dataStore object has been set
  • // as the hash, return it.
  • return( originalData.apply( this ) );
  •  
  • } else {
  •  
  • // No special case, simply pass method call
  • // to original method and return the result.
  • return(
  • originalData.apply( this, arguments )
  • );
  •  
  • }
  •  
  • };
  •  
  • })( jQuery );
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // When the DOM is ready, init the scripts.
  • jQuery(function( $ ){
  •  
  • // Get a reference to the P tag.
  • var para = $( "p:first" );
  •  
  • // Get a reference to the data storage struct.
  • // When you call the data() method without any
  • // arguments, jQuery returns the actual storage
  • // object, not a duplicate of it.
  • dataStore = para.data();
  •  
  • // Now that we have the data storage object, we
  • // can update the values in it directly.
  • dataStore.name = "Tricia";
  • dataStore.isSexy = true;
  •  
  • // Now that we have updated the store object, let's
  • // update the text of the paragraph by re-referencing
  • // the data storage mechanism.
  • //
  • // NOTE: We did NOT have to re-store the data object
  • // in order to make these values available.
  • para.text(
  • para.data( "name" ) +
  • " is " +
  • (para.data( "isSexy" ) ? "" : " not " ) +
  • "sexy!"
  • );
  •  
  • });
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • Calling jQuery's Data() Method Without Arguments
  • </h1>
  •  
  • <p>
  • <!-- Will be populated dynamically. -->
  • </p>
  •  
  • </body>
  • </html>

As you can see, the first part of this script overrides jQuery's native data() method to intercept and manipulate calls to the data() method made without any arguments. If the data() method returns null, I store the key, "_", in the element's data cache before re-querying the data() method to return a valid data cache object reference. In doing so, the rest of the demo can successfully retreive the data cache using the data() object regardless of the current state of the cache. In doing so, I am able to directly mutate the data cache without making unnecessary calls to the data() method. And, since this data cache is returned by reference, my data alterations are reflected in subsequent calls to the data() method.

When we run the above code, we get the following paragraph output:

Tricia is sexy!

As you can see, the direct data manipulation we performed on the data store object was successfully reflected in later calls to the data() method.

jQuery 1.4 finally gave us the ability to directly access the data cache being used by the data() method. The behavior of this method, however, depends tightly on the current state of the cache. To me, this difference in data() behavior feels unnecessary; and, while the above solution is not perfect by any means, I like that it simplifies the way in which the data() method can be used.




Reader Comments

Feb 1, 2010 at 11:02 AM // reply »
2 Comments

Hi Ben,

Suggest some good tutors/books to learn this JQuery framework.

Thanks!


Feb 1, 2010 at 11:19 AM // reply »
11,238 Comments

@Dave,

I think the fastest, low-level intro to the language would probably be Cody Lindley's jQuery Enlightenment book:

http://www.bennadel.com/blog/1713-jQuery-Enlightenment-By-Cody-Lindley.htm

Once you are comfortable with that, there are a number of other great jQuery books that I have reviewed on this site:

http://www.bennadel.com/blog/tags/12-Books-blog-entries.htm

Try looking at jQuery Cookbook, jQuery in Action, Learning jQuery, and the jQuery UI books. These are all great books and go into more depth.


Feb 1, 2010 at 12:06 PM // reply »
2 Comments

Thanks Ben!.. Will give them a try!.


Feb 2, 2010 at 12:34 PM // reply »
1 Comments

Is this new in 1.4?


Feb 2, 2010 at 12:43 PM // reply »
11,238 Comments

@Peter,

Calling data() without arguments... but not the data() method itself.


Jan 14, 2012 at 6:44 AM // reply »
1 Comments

Hi Ben,

Why it works in ie6-9,ff,safari&chrome but not in opera 11.60? Btw, i like your code so much.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools