Validating a MongoDB object id

 
If you’re working with MongoDB then sooner or later you’re likely to hit an error when inserting or updating a document with a badly constructed Object Id.

For example:


db.mycol.insert({
  "_id": ObjectId("5289e30bcc93743934044d2Z",
  "name": "dvolr"
})

run in the Mongo shell will result in an “Error: invalid object id: not hex” message.

Of course, it’s better to catch this error before even attempting the database update.
This one line Javascript function uses a simple regular expression to check that the id is a 24-character hex string (i.e. only characters 0 to 9 and A to F). It will work in the browser and Node.js.


function isValidObjectID(str) {

  // A valid Object Id must be 24 hex characters
  return (/^[0-9a-fA-F]{24}$/).test(str);

}

// This one returns 'true'
alert( isValidObjectID('507f1f77bcf86cd799439011')

// This one returns false (notice the 'Z')
alert( isValidObjectID('507f1f77bcfZ6cd799439011')

I’ve also created a JSFiddle if you want to try it out with some other values.


More:

Why your jsFiddle no longer works (and how to fix it)

 
If you’re unfamiliar with jsFiddle I recommend you check it out – it’s a great, free playground and an essential tool for web developers. So essential that, over the last few years, it has become almost mandatory for Javascript developers to create a jsFiddle to collaborate on problems with remote colleagues, to offer a library with working, interactive examples, to test proof-of-concepts or to troubleshoot errant code. I’ve lost count of the number of requests for help on Stack Overflow whose first reply is “jsFiddle or it didn’t happen”.

Combining jsFiddle’s interactivity with GitHub’s hosting and version control can greatly increase uptake of your public project. By linking your jsFiddle to GitHub’s raw output you can offer a no cost, no download, no fuss intro to your code.  Instead of asking fellow developers to download and set up your GitHub hosted library you can provide working code examples that instantly show how your code should be used and if it does what they expect it to in they way they expect it to do it. Or rather, that used to be the case. Recent browser changes, particularly to Google Chrome, mean than many existing jsFiddles no longer work. There’s no obvious error but no output appears in the Result.

Click to embiggen

The problem

The problem is simple enough – the external Javascript libraries we are loading from GitHub are no longer being executed. To see why, we need to take a step back. Let’s assume we have a library in GitHub that we want to use in jsFiddle.  To do so, we add the URL of the raw GitHub source in the External Resources section of jsFiddle. This has been common practice for years and used by pretty much everyone because it was easy, convenient and, best of all, it worked.

Adding an external resource to a jsFiddle
Adding an external resource to a jsFiddle. Here, the jlist-min.js library is being loaded directly from raw.github.com.

 

Unfortunately, it worked despite the fact that it shouldn’t have. Files served from raw.github.com are served with a content-type of text/plain. This didn’t used to matter but browsers such as Google Chrome have tightened up security and will now only execute Javascript code that has a content-type of application/javascript . If we look at the console in Chrome Dev Tools while in a jsFiddle that links to raw.github.com we can see the problem:

The error that appears in the Google Chrome console when we link to raw.github.com.
The error that appears in the Google Chrome console when we link to raw.github.com.

What was once acceptable (and very common) practice no longer works.

The solution

Luckily the solution is both simple and less wordy than the problem.
There is a 3rd-party service which will proxy the file you need from raw.github.com and change the content-type before your browser receives it.
To make use of this service, all you need do is remove the full stop (period) from between raw and github in the offending url.
That is

http://raw.github.com/rest_of_the_path

becomes

http://rawgithub.com/rest_of_the_path

 

and your jsFiddle is working again.

 

More:

jList 1.6.0: Eight new functions added

Earlier today I pushed jList 1.6.0 to GitHub. This version of the library, which brings ColdFusion-style list handling to Javascript, adds eight new functions, bringing the total to thirty:

  • listConcatenate
    Adds one list to the end of another.
  • listDifference
    Returns the elements that are unique to each of two different lists.
  • listIntersection
    Gets the elements that are common to each of two different lists.
  • listRemove
    Removes elements in one list from another list.
    Matching is case-sensitive.
  • listRemoveNoCase
    Removes elements in one list from another list.
    Matching is not case-sensitive.
  • listReplace
    Replaces any occurrences of an element in a list with a different element.
    Matching is case-sensitive.
  • listReplaceNoCase
    Replaces any occurrences of an element in a list with a different element.
    Matching is not case-sensitive.
  • listUnion
    Combines the elements from two different lists.

For the first time, these changes were not made by me but by Chris Tsongas. This was the first time Chris had contributed to an open source project and he did a great job of adding new functionality as well as making sure all of the tests and documentation were brought up-to-date.

All documentation is updated so full details of the new functionality is on the jList GitHub page.

All eight new functions have also been added to jsFiddle should you wish to try them out first –

listConcatenate

listDifference

listIntersection

listRemove

listRemoveNoCase

listReplace

listReplaceNoCase

listUnion

jList 1.6.o can be downloaded for free from GitHub.

More:

Previously:

jList 1.5.0: Two new functions added

Even though I wrote the original, rather messy, version of jList over five years ago I’ve never had the need for a listContains function i.e. one that searches a list looking for an item which at least partially matches a string. Until now, that is.

Yesterday I pushed jList 1.5.0 to GitHub. This version of the library, which brings ColdFusion-style list handling to Javascript, adds two new functions, bringing the total to twenty-two:

  • listContains
    Determines the index of the first list element that contains a specified substring.. The search is case-sensitive.
  • listContainsNoCase
    Determines the index of the first list element that contains a specified substring. The search is not case-sensitive.

These functions look at each individual element of a list for a specific value.  Where the value being searched for is wholly or partially contained within an element  then the position of that element in the list is returned. Where no match is found, zero is returned.

For example:


jList.listContains("cat,dog,mouse,rabbit,lion", "bit")

would return 4 even though the value itself is not in the list.

All documentation is updated so full details of the new functionality is on the jList GitHub page.

The two new functions have also been added to jsFiddle should you wish to try them out first – listContainslistContainsNoCase.

jList 1.5.o can be downloaded for free from GitHub.

More:

Previously:

Javascript: Accurate timing is (almost) here

If you’ve ever tried to optimize or locate a bottleneck in your Javascript code you’ve most likely ended up using Date().getTime(). As this function returns the number of milliseconds since the 1st of January, 1970 we can easily determine the total run time of the code we wish to test by taking two readings, one immediately prior to the code to be tested and and one immediately after. A simple subtraction will then give us the total run time in milliseconds:


var start, end;

start = (new Date()).getTime();

// Run a test

end = (new Date()).getTime();

alert(end - start);

While this is easy to use and consistently implemented across browsers it has a three flaws that make it less than ideal for benchmarking – the value returned is an integer so it’s useless for timing anything that takes less than a millisecond, it’s derived from the system clock which may be unstable or subject to adjustment and, depending on the operating system and browser, can be significantly wrong.

With the recent release of Google Chrome 20 to beta we now have the opportunity to use a new, more reliable and more precise timer – High Resolution Time a.k.a.  performance.now. More specifically, we can use the Chrome, vendor-prefixed, version – performance.webkitNow.

As performance.webkitNow returns the number of milliseconds since the navigationStart of the page and is not tied to the system clock we get more reliable timings. Better still, it returns the elapsed time as a double with microseconds in the fractional part, allowing us to have more accurate, sub-millisecond, timings.

If we rewrite the previous example to use High Resolution Time instead of Date().getTime() our code would be:


var start, end;

start = window.performance.webkitNow();

// Run a test

end = window.performance.webkitNow();

alert(end - start);

Running this example would give us results such as 0.005999987479299307 whereas our original, Date-based, example consistently returned zero.

Of course, it’s never so simple. This will work fine in Chrome 20 Beta but will error in all other browsers (and earlier versions of Chrome). To allow for other, as yet to be released, vendor-prefixed versions and to be usable today we must create a small shim function:

 var now = (function() {

// Returns the number of milliseconds elapsed since either the browser navigationStart event or
// the UNIX epoch, depending on availability.
// Where the browser supports 'performance' we use that as it is more accurate (microsoeconds
// will be returned in the fractional part) and more reliable as it does not rely on the system time.
// Where 'performance' is not available, we will fall back to Date().getTime().

var performance = window.performance || {};

performance.now = (function() {
return performance.now    ||
performance.webkitNow     ||
performance.msNow         ||
performance.oNow          ||
performance.mozNow        ||
function() { return new Date().getTime(); };
})();

return performance.now();

});   

This will use the “official” performance.now, if it is available. If not it will try each of the vendor prefixes, then ultimately fall back to Date().getTime(), allowing for all eventualities now or in the near future. Using this function is no more difficult that our previous examples:


var start, end;

start = now();

// Run a test

end = now();

alert(end - start);

 

You can try out this function on jsFiddle or grab it from Gist or Snipplr.

 

More:

jList: Version 1.3.0 adds three new functions

Today I pushed version 1.3.0 of jList to GitHub. This version of the library, which brings ColdFusion-style list handling to Javascript, adds three new functions, bringing the total to twenty:

  • listChangeDelims
    Changes a list delimiter.
  • listValueCount
    Counts the instances of a specified value in a list. The search is case-sensitive.
  • listValueCountNoCase
    Counts the instances of a specified value in a list. The search is not case-sensitive.

All documentation is updated so full details of the new functionality is on the jList GitHub page.

The three new functions have also been added to jsFiddle should you wish to try them out – listChangeDelims, listValueCount, listValueCountNoCase.

Previously:

jList: All functions now available in jsFiddle

jsFiddle is a free, browser-based, application for creating and running snippets of HTML, CSS and JavaScript. As each snippet is given a unique URL it can easily be shared, making it a great tool for testing, experimentation and collaboration.

All of the functions in the jList library, which brings ColdFusion-style list handling to Javascript, are now available as public snippets in jsFiddle so that you can try them out without having to download the source from GitHub. The fiddles available are:

 

Full list of fiddles

 

listAppend

listDeleteAt

listFind

listFindNoCase

listFirst

listInsertAt

listLast

listLen

listPrepend

listQualify

listRemoveDuplicates

listRemoveDuplicatesNoCase

listRest

listReverse

listSetAt

listSort

 

More:

 

Previously: