Thursday, November 11, 2010

Custom Events in AS3

This summary is not available. Please click here to view the post.

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

    Passing arguments to an event

    You probbably don't know this but AS3 and JS have a multi-paradigm, imperative and functional. This right now for us means that a function has the same rights as a regular Number. This is something so useful it hurts.

    Try this...

    function helloWorld(s){
     trace(s);
    }
    var helloWorld = 0;
    

    You may get this error:

    Scene 1, Layer 'Layer 1', Frame 1, Line 5 1151: A conflict exists with definition helloWorld in namespace internal, bitch.

    Ok, not the last part. But there is a conflict. Why would there be a conflict? is a function a variable? In AS3, yes. For years the functions have been living under the shadow of variables, but now the functional paradigm considers them as equal! mwahahaha! Make no mistake, this a russian roulette full of bullets pointing the hard work of modular code :)

    In AS3 you have events, its listeners functions can only recieve one argument, the event itself. The event is a simple variable that the only true interaction that has with the rest of the scope is the target element. Sometimes we may want to pass some relevant information to the event listener to trigger some cool stuff, there are many alternatives for doing this, you may use class attributes or implement a singleton pattern to create static content readable everywhere.

    But let's believe for a second that you just want to pass a single miserable variable to the listener. Many purist will say that you need to extend the Event class and make your own event, just to handle it. Let me tell you... they haven't enter the rabbit hole of functional programming.

    If you know nothing of functional programming I reccomend a haskell crash course. Let me show you the solution, then if your head is still over your shoulders or you manage to avoid passing out, because this is gonna be cool (i'm being sarcastic) i'll explain.


    function hello(s,e){
     trace("hello... "+s);
    }
    
    var  girl = "nurse";
    
    stage.addEventListener(Event.ENTER_FRAME,function(e){hello(girl,e) 
    /*do extra stuff involving the arguments or whatever you wanna do*/
    });
    

    So, this function basically traces the line "hello... nurse" every time a frame is drawn. I'm even passing the event, so you're basically passing arguments to the event listener.

    This saves you the trouble of extending the Event class, creating a new property o telling the client that it can't be done. Some people may argue that this is a lazy and impractical solution, they'd be wrong. There's nothing wrong with this, is not cheating. And some people will try to make you cry, that's a different blog.

    A little trouble with inlining functions is that they don't have a name, and I don't mean that in the nameless kinda way from the Jet Li films, this is not cool. Inlining a function like this may be a problem when changing it. Let's fix that...

    function hello(s,e){
     trace("hello... "+s);
    }
    
    var  girl = "nurse";
    
    var listener;
    
    stage.addEventListener(Event.ENTER_FRAME, listener = function(e){hello(girl,e) 
    /*do extra stuff involving the arguments or whatever you wanna do*/
    });
    

    There you go, now you have passed arguments to an event listener in a dynamic, simple and clean way. There's some lazy syntax around here, but i'll talk about in a future. there's some reference issues that also will be adressed in future posts.

    Now, off you go... go clean up your code, delete all those useless extended event classes, embrace the functional paradigm and go tell the woman you love that you are a true man.

    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

    I'm not going to say hello world...

    Hey people, first post. As usual i have to make a reference to the usual "hello world" crap, in this case i make a quick reference to the rebel stand that the Core Java book once took.

    I'm not saying hello world.

    This blog will cover my adventures and misadventures in the world of AS3, Jquery/Javascript, CakePHP and whatever framework or language i'll be using for the rest of my internet life, or as long as this blog is used. Feel free to comment, share, send money, touch yourself, lolcat or whatever you wanna do while reading this place, bitch.

    I'm sorry, i'd had to write bitch in my first post. Let this be the first of millions of posts that will make the google servers asplode.