Hugoware

The product of a web developer with a little too much caffeine

jLinq 2.2.0 Released!

with 15 comments

Ever hear of jLinq. If not, it’s no big deal. Its a personal project of mine to make a LINQ style query language for Javascript. With all these “Web 2.0” applications floating around, the ability to sort, query and manage your records on the client side may become a necessity. Use jLinq with the JSON data you already have and you’ve got quite a combination.

If you haven’t tried it out, there is an online version available you can use to see it in action.

Below are some of the new features in jLinq 2.2.0.

Smarter Comparisons

Let’s say you ran the command below…

jLinq.from(users)
    .less("firstname", 5)
    .select();

Seems simple enough, first names less than 5 characters long?

Nope…

The previous version of jLinq expected certain data types depending on the command. For example, if you used less, lessEquals, greater, greaterEquals, between or betweenEquals then the expected parameter was a number as was the field you were querying against.

In the new version you’ll find code like this when checking values.

//get the the parameter value
value = query.helper.when(value, {
number:function() { return value; },
other:function() { return value.length; }
});

//determine how to check this against the value
return query.when({
string:function() {
return (query.value.length < value); }, array:function() { return (query.value.length < value); }, other:function() { return (query.value < value); } }); [/sourcecode] Instead of making any assumptions, jLinq now checks the types and returns the values required to make the query work. For example, if you use 'less' with a string value, the length property is automatically used instead of the string value itself. jLinq also is more intelligent with different command types. For example, the .contains() used to work with string values only. Now it works with arrays or converts a value to a string then checks the result.

11 New Commands

  • attach(alias, function): Executes and attaches the return value of your function onto the record using the alias name you provice.
  • sum(field): Returns an object with information about the sum of the field name used.
    returns {
    count:the number of records counted,
    result:the sum of all records selected,
    records:the records used to find the sum
    }
  • average(field): Returns an object with information about the average of the field name used.
    returns {
    total:the sum before the average was calculated,
    count:the number of records used,
    result:the average of all records selected,
    records:the records used to find the average
    }
  • max(field): The maximum value found for the field name provided.
  • min(field): The minimum value found for the field name provided.
  • except(collection): Compares a second set of records and only returns records that are not found in the comparison list. Returns a new jLinq object. (example)
  • intersect(collection): Compares a second set of records and only returns records that are found in both lists. Returns a new jLinq object. (example)
  • union(collection): Compares a second set of records and only returns records that are unique in both lists. Returns a new jLinq object. (example)
  • skipWhile(delegate): Skips selecting records until the first ‘false’ result is returned from your function. After that point, all records are selected. Returns an array of results. (example)
  • takeWhile(delegate): Selects records until the first ‘false’ result is returned from your function. After that point, all records are ignored. Returns an array of results. (example)
  • selectMany(collection, compareFunction, selectionFunction): Compares each value of the current query against the provided collection array (example). For each successful comparison a new record is added to your results. If you use your own selection method then you need to write a function similar to function(queryRecord, compareRecord) {. The return value will be added to the list. If no selection method is used, then the following object is returned.
    returns {
    source:the record in the jLinq query that is compared,
    compare:the record in the collection array that is compared
    }

Bug Fixes

There was an Opera bug when you tried to sort records. I’m not sure that I understand why, but basically, there really is a difference between for loops in Opera.

jLinq Testing

If you’re interested in creating your own jLinq extension methods you can now download a series of tests that you can use to determine that your command doesn’t break anything else in jLinq.

Wrapping Up

Whew! You’re still with me? You must be dedicated!

Right now I realize that there still may be some confusion on how to use jLinq. I’m currently working on some screencasts that I can share to help people get started.

If you have some requests on what you would like to see in an upcoming screencast, please send me your ideas and I’ll add them to my list.

Source Code

Download jLinq-2.2.0.js

.

Written by hugoware

June 28, 2009 at 3:04 pm

15 Responses

Subscribe to comments with RSS.

  1. jLinq 2.2.0 Released! « Yet Another WebDev Blog…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

    DotNetShoutout

    June 29, 2009 at 6:43 am

  2. Amazing! keep it up. Good job

    Muhammad Mosa

    June 29, 2009 at 8:10 am

  3. How about support for accessors.If I’ve some array of objects with get*() methods,returning arrays in turn.What if I want synthetic “firstname” property for get*() method?
    I’m talking about Joose integration:-)

    Thanks.

    Andrey Skvortsov

    June 30, 2009 at 10:06 am

    • Actually, you can — Check out this page in the docs…

      http://jlinq.net/docs/?tipsandtricks

      Basically, when you access the field itself, methods or array indexes… so for example…

      //method names
      jLinq.from(data).greater(“totalSum()”, 50)

      //array indexes
      jLinq.from(data).equals(“permissions[0]”, “read”);

      You can actually even take it a step further and access the object that is returned like..

      jLinq.from(data).equals(“manager.name.first.charAt(0)”, “s”);

      webdev_hb

      June 30, 2009 at 10:20 am

      • Thanks,it’s actually help a little.But I still prefer implicit over explicit property mapping(by convention)-it’s simply more natural IMHO.Accessor methods are unavoidable in legacy JS,but things changes and future versions of JS seems to support implicit property accessors.It seems natural to me to implement them on framework level.
        What do you think about http://github.com/jcrosby/jsonquery/tree/master and JSONPath in general?Don’t you think you complicate things slightly- “from(…).select(a).select(b).select(c)”… maybe “from(…).select(“a.b.c”)” a little easier?

        Andrey Skvortsov

        June 30, 2009 at 11:10 am

      • I’m not sure that I follow you. Could you write a sample query (not like the a.b.c one below) that shows what you are suggesting? I’m very interested to hear your thoughts .
        Thank you

        webdev_hb

        June 30, 2009 at 12:09 pm

  4. I’m talking about:
    “Performs a recursive search for the given property name, returning an array of all values with such a property name in the current object and any subobjects”-from http://docs.persvr.org/documentation/jsonquery . In essenсe,I’m talking about “true” query language for “select” a’la XQuery/XPath,with “axis” parent/child navigation support for descendants of “from” object.For example:
    “a..b[c]”-filter all “b” properties on any level of object graph.Look at JSONPath docs for details.

    Thanks.

    Andrey Skvortsov

    June 30, 2009 at 12:21 pm

    • Interesting concept – I think I understand what you’re saying about parent/child navigation.

      As for now, you can get partial child navigation by just using the actual name of the object as you saw in the example before.

      Parent navigation seems possible, but I’d have to experiment to say for certain.

      Thank you for your suggestions!

      webdev_hb

      June 30, 2009 at 12:40 pm

  5. […] jLinq 2.2.0 Released! – LINQ style query language for Javascript. Feels like jQuery for data. […]

  6. Awesome stuff! I have used this on a project and what a time saver. You really have created something great. By the way, I didn’t “link” you to jLing until a moment ago. I was at Hugoware.net, jumped to your article on CodeProject and after a series of hops ended up back here.

    Now I really want to know what you think of Silverlight! Don’t give the Javascript stuff dude!

    ActiveEngine Sensei

    July 31, 2009 at 6:31 am

    • Haha – Yeah, I didn’t do a good job creating an “online presence” for myself — I’m scattered around the web with several different aliases.

      jLinq is still worked on from time to time (mostly screencasts now). I haven’t gotten much feedback on what people would like to see added and I’m not personally getting any new ideas! 🙂 (I already copied as much as I could from the 101 LINQ Samples page!!)

      In any case, I appreciate the compliment! Let me know if you have any ideas to make it better!

      webdev_hb

      July 31, 2009 at 8:08 am

  7. […] with 2 comments A newer version of jLinq is now available – jLinq 2.2.0 […]

  8. Hi, this is really nice stuff!

    For a source of inspiration and new ideas, check out the Rx (Reactive framework), using LINQ for async events.

    Intro here:
    http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html

    Perhaps you can extend your elegant approach to Linq in Javascript to be used for chained event processing (instead of deeply nested callbacks).

    With all that Ajax and events driven UI programming in browsers, this may be a very valuable extension.

    luc

    October 16, 2009 at 4:00 am

  9. Thanks for another great post. Where else could anyone get that kind of info in such an ideal way of writing? I have a presentation next week, and I’m on the look for such information.

    read

    February 20, 2021 at 12:29 am


Leave a reply to DotNetShoutout Cancel reply