Chuck Norris There's only one thing more awesome than Chuck Norris...

And that's Chuck Norris jokes!

Over at the Internet Chuck Norris Database (or ICNDb for short) you can find literally hundreds of Chuck Norris jokes.

Nestled amongst the archives you can find the classic ones:

Chuck Norris once ordered a Big Mac at Burger King, and got one.

And you can find the nerdy ones:

All browsers support the hex definitions #chuck and #norris for the colours black and blue.

But better than the jokes themselves, the ICNDb boasts a RESTful API for easy access!

Wow! Just think, all your applications could sport a daily Chuck Norris joke!

The API lets you retrieve random jokes, jokes by ID and jokes by category. Not only that, it even lets you change the words Chuck Norris to any name you want! Be it your name, your friend's name or your Mum!

To lend a helping hand I've written a Fantom client for the Internet Chuck Norris Database.

Using the IcndbClient is easy:

class Example {
    Void main() {
        client := IcndbClient()
        echo(client.noOfJokes)    // --> 546
        echo(client.categories)   // --> [explicit, nerdy]
        echo(client.random.joke)  // --> Love does not hurt. Chuck Norris does.
        echo(client[461].joke)    // --> Chuck Norris finished World of Warcraft.
        
        echo(IcndbClient("Emma", "Statham") { it.limitTo.add("nerdy") }.random.joke)
        // --> Emma Statham can install a 64 bit OS on 32 bit machines.
    }
}

And here is the IcndbClient itself. It's only about 69 lines of Fantom code:

using util
using web

** The Internet Chuck Norris Database Client
class IcndbClient {
    private Uri icndbUrl := `http://api.icndb.com/`

    Str?  firstName
    Str?  lastName
    Str[] limitTo := [,]
    Str[] exclude := [,]
    
    new makeWithName(Str? firstName := null, Str? lastName := null) {
        this.firstName = firstName
        this.lastName  = lastName
    }
    
    @Operator
    Joke get(Int id) {
        Joke(fetch(`jokes/${id}`, true))
    }
    
    Joke random() {
        Joke(fetch(`jokes/random`, true))
    }

    Str[] categories() {
        fetch(`categories`, false)
    }
    
    Int noOfJokes() {
        fetch(`jokes/count`, false)
    }
    
    private Obj fetch(Uri url, Bool addQuery) {
        if (addQuery) {
            query := ["escape":"javascript"]
            if (firstName != null) query["firstName"] = firstName
            if (lastName  != null) query["lastName"]  = lastName
            if (!limitTo.isEmpty)  query["limitTo"]   = limitTo.toStr
            if (!exclude.isEmpty)  query["exclude"]   = exclude.toStr
            url = url.plusQuery(query)
        }

        json := WebClient(icndbUrl + url).getStr.replace("\\'", "'")
        try {
            data := (Str:Obj?) JsonInStream(json.in).readJson
            return data["value"]
            
        } catch (ParseErr err) {
            msg := json.replace("<br />", "").replace("<b>", "").replace("</b>", "").replace("\n\n", "\n")
            throw ParseErr(msg)
        }
    }    
}

const class Joke {
    const Int   id
    const Str   joke
    const Str[] categories
    
    internal new make(Str:Obj? data) {
        this.id         = data["id"]
        this.joke       = data["joke"]
        this.categories = data["categories"]
    }
}

Have fun!


Discuss