Live geek or die tryin'

A Fix for Select2 Not Displaying Results on IE

When using Select2, filling a select box, and not seeing any result, chances are that you’re querying a different server, which requires CORS, which in turn isn’t supported by Internet Explorer (9.0 and below).

Using the jQuery-ajaxTransport-XDomainRequest plugin fixes the problem.
Explanations are in the README.

(this problem is of course not specific to Select2, but given the layers of code/libs between the developer and the creation oFJthe XHR object inside jQuery’s ajax() function, one might forget this detail like I did)

Use Java 7 for IntelliJ’s SBT Plugin

IntelliJ IDEA runs on JRE 6, and so does its SBT plugin.

If you need to use a more recent version of Java (and you should):

  • Open the Preferences panel
  • Go to the SBT section
  • Tick the Use alternative JRE option
  • Click the arrow on the right of the field to check if the IDE suggests the desired JRE
    • If so, choose it.
    • Otherwise, look for the path by yourself.
      It’s /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home on my Mac.

WebSockets: INVALID_STATE_ERR: DOM Exception 11

This error can be caused by many reasons, among them what happened to me: I tried sending a message via the WebSocket before the connection was completely opened.

What you should not do:

ws = new WebSocket("ws://localhost/ws");
ws.send('foo');

What you should do instead:

ws = new WebSocket("ws://localhost/ws");
ws.onopen = function () {
  ws.send('foo');
}

Java: No Main Manifest Attribute

I won’t go though explaining how to create a build.xml file, the official manual, which is really good, does it better than I would.

The error in question occurs because the java executable, after reading the Manifest file from the inside of the JAR, doesn’t know what is the entry point of the program; i.e. the class that contains the ugly public static void main(String[] args) method.

To fix the error, that class’ full name needs to be specified in the build.xml file.
For example:

<jar destfile="${jar}" basedir="${build}">
    <manifest>
      <attribute name="Main-Class" value="my.awesome.package.Main" />
    </manifest>
</jar>

Building a Search System With MongoDB (and Scala)

If you need a search system for your web application, you can either roll your own, or use a system that does it for you, such as elasticsearch.
I’ve recently had to choose, and the second option was an overkill since I was looking for something simple.

The main idea here is using an index collection, let’s call it searchresults, that will be updated each time the real entities change, thanks to hooks implemented on the default create/update/delete tasks.
searchresults will be the only collection to get queried, thus making requests simple and search results’ retrieval fast.

More in details

I’ll use two entities in my example: User and Song.

The SearchResult model has 3 fields:

  • entityType: a discriminator field that contains the indexed entity type, user or song in this case.
  • entityId: You think my name is Captain Obvious, don’t you?
  • keywords: An array of keywords related to that search.

That class’ signature should look like this:

case class SearchResult(
  id:         ObjectID,
  entityType: String,
  entityId:   ObjectID,
  keywords:   List[String]
)

Paired with the class described above, a Searchable trait will help forcing the implementation of some methods and properties, and more importantly be used as a type in methods signatures.

trait Searchable {
  def entityType:    String = this.getClass.getSimpleName,
  getSearchKeywords: List[String],
  entityId:          ObjectID
}

Now, each of your entities class, User and Song, will implement the Searchable trait, define the entityType property and implement the getSearchKeywords() method. The entityId property, or some entity with the same name, should already be implemented by your MongoDB driver.

Example of a getSearchKeywords() method:

def getSearchKeywords: List[String] =
  List(this.username, this.firstname, this.lastname).filter(_.nonEmpty)

The next step is to implement the hooks that update the index collection each time users and songs are updated too.

If you use Casbah and Salat for instance, the entities are created and updated when calling the save() method, and deleted when remove() is called.
These methods should be overriden, the hooks behaviors added to them —creating or updating the concerned SearchResult entry, in case of save() for example—, yet without altering their initial role.

override def save(user: User) {
  createSearchResult(user, SearchResult.findByEntity(user))
  super.save(user)
}

private def createSearchResult(user: User, searchResult: Option[SearchResult]) {
  searchResult match {
    case Some(sr) => SearchResult.save(sr.copy(keywords = user.getSearchKeywords))
    case None => SearchResult.save(SearchResult(
      entityType = user.entityType,
      entityId   = user.id,
      keywords   = user.getSearchKeywords
    ))
  }
}

The last thing to do, is creating a MongoDB index on the keywords field of the searchresults collection.
This can be done in one single command:

mongo myAwesomeDB --eval "db.searchresults.ensureIndex({keywords: 1});"

We’re done. I guess.