Showing posts with label json. Show all posts
Showing posts with label json. Show all posts

Sunday, July 18, 2010

understanding JSONP with twitter and jquery, and stuff

The saddest moment in the life of a frontend developer is when you found out about the cross-domain restrictions. Is a very similar situation for all of us...

We manage to found ourselves coding something, we make a request from a different server. Most of the times we think "hey! i want sport news! I'll just .load the homescreen from espn.com, then i want sexy women in my site! let's leak out images from maxim", you do this and nothing works... you wonder why...

Imagine if an ajax request could send and load data from any website. You could easilly load personal information from your gmail, facebook and redtu... i mean, youtube. Not a safe path. There are workarounds for this, the basic case is JSONP. Other workaround is a flash proxy, but we'll discuss that one later.

Time to understand JSONP and get down and dirty, in a computer kinda way. JSONP is all about making an ajax query to a server. Imagine you import this script from a different domain...

function thisisajsonp(){
    return {"name": "cristian", "age": 23}
}

Of course, this content was created dinamically. there you go... that's JSONP, basically. Now let's do something interesting with it.

Twitter has many services available, the ones that involve user account related actions do need some OAuth server side work. Nevertheless the search method is as open as a drunk undergrad chick, and it has a JSONP service.

We can do this http://search.twitter.com/search?q=fml, we tell twitter to search for the "fml" pattern, that's the "q" parameter (for a the full list of parameters click here -> the last here, not this one), Try it.

if do this http://search.twitter.com/search.json?q=fml we retrieve a jsonp format instead. We can loop through this format. The structure of this json object is kinda messy if you try to read it in plain, I recommend exploring it with firebug when we load it later, it's easier to understand. Ok, guns blazing, I'm coding...


click to load!


    Firts, the HTML. We have a div called "trigger", when we click there we'll load the tweets to the tweets list. Simple, now the JS... mwahahah!

    $(function(){
                $("#trigger").click(function(){
                    $("#tweets").text("");
                    $("#trigger").text("loading");
                    $.getJSON("http://search.twitter.com/search.json?callback=?",{q:"fml"},function(data, textStatus){
                        $.each(data.results, function(i,tweet){
                            $("#tweets").append("
    
  • "+tweet.text+"
  • ") }) $("#trigger").text("click to load!"); }) }) });

    FYI, you need to know some basic jquery to understand this blog, and be somebody. The method we use is getJSON, we pass some parameters, the URL, the data, and the callback function to handle the data.

    This blog is about details, the loopholes in coding that can seriously pull back your schedule (wow, that was like... serious). So, the details here are simple, if you look to the URL you may see i wrote "callback=?", why would I do that? Here's the answer...


    down here....



    further down....


    That way Jquery understands that the format comes from a different domain, and loads the data dynamically. In the first example I showed you how the remote querying could work, a function that returns the data. Functions have a name, if that name is repeated well... it won't work :) so, we can pass the function name, sometimes (most of the time) you don't care what the name of the function is, so it's a pain in the ass to declare a function just for the sake of having something to invoke, jquery does that for you, this function is called "padding". Is like this:

    Jquery: hey dude, what's the name of the padding for the data fetched?
    You: ?
    Jquery: nevermind, i'll handle it.

    Just put the "callback=?" in the URL.

    The rest of the code is some basic status handling and looping throught the object. Nothing big, as a matter of fact if you click it several times on a row you will load repeated data, it's just an example, we are not building a twitter client here.

    If you have any question remember you can google it, you can also follow me @cris7ian, everything is in spanish "tengo un gato en los pantalones" kinda way, but if you contact me I'll answer you un plain english (that's what twitter is all about).

    Thursday, July 15, 2010

    cloning json, arrays and stuff...

    A few weeks ago i had to handle this really big object (in JS, i'm not gay). I remembered the joke:

    -Mommy, mommy the kids won't let me implement a swap function in javascript
    -That's because it's impossible, the javascript language passes arguments by value, not reference. You dumbass.

    Ok, that joke doesn't exist, is not even funny. The point is that sometimes you may have a json object or an array that you just wanna pass around without further complications. You may also have a json object with arrays inside, etc.

    var person = {personality: "moron", age: 23, name: "Cristian"}
    var cristian = person;
    person.name = "Cris";
    

    Voila! I changed the name of cristian. So far you may know this, and if you don't know it then you might not be such a sniper with JS. There's a solution for this problem, is simple, clone the object, cool. The only problem is that there are no classes in JS, there is an object representation which is as flexible as melted rubber band. So, we CAN do cloning for what it may be a representation of a class, this is a pain in the ass. You may have to implement a method for every object you have, where all you do is copy the properties to another object, and its structure.

    I can't imagine looping through each object over and over again. Arrays in arrays, objects in arrays, etc.

    Being JS so flexible, we should be capable of implementing a generic cloning function. Being this the case, and being myself such a lazy bastard, i came up with this solution.

    function cloneObj(stuff){
                if(stuff == null || typeof(stuff) != 'object'){
                    return stuff;
                }
                var temp = new stuff.constructor();
                for(var key in stuff){
                    temp[key] = cloneObj(stuff[key]);
                }
                return temp;
            }
    

    Simple method, how does it work? i loop through all the elements, and if the element is an object I do the same for its inner elements. In the end I get a brand new object.

    Is this the best solution ever? no, it would ve even cooler to make it a general method, but being as freaking flexible as it is cloneObj can clone any objectish-arraysh-tree-like structure, for real.

    Also, the recursive stack in JS is kinda small, so you may get a "too much recursion" error when cloning something big (i mean BIG). It would be cool to make some dynamic programming so this won't happen and make the method lighter.

    So, there you go. A little snippet that may save your life if you ever find yourself in a swordfish movie like situation