views:

26

answers:

2

I have two lists, one on the right and one on the left. When I click on a node on the left it does the following:

1) AJAX request $.post's the content of the node to the server

2) If the transaction is successful on the server, the node moves to the list on the right via jQuery

To post to the server:

$.post($(F).attr('action'), $(F).serialize(), null, "script");

To move the node to the other list:

moveNode(element, to_list);

'element' and 'to_list' are local variables. I could make moveNode the callback, but if the transaction is not successful, I'll have to post a bunch of error messages and things get clunky in my code. I'd also like the server to generate the error messages.

Is there any way to place the call to moveNode() in the server response?

+1  A: 

You can parse a response from the server in the callback (json encoded perhaps) with error messages and a boolean telling if the transaction is successful or not. Then run your moveNode() depending on the response.

$.post($(F).attr('action'), $(F).serialize(), function(response) {
   if (response.successful) {
     alert('yay');
     moveNode(element, to_list);
   } else {
     alert('Error: ' + response.error);
   }
}, "json");
baloo
+2  A: 

It's possible to do what you want, but I wouldn't recommend it. Here's how:

function doTheThing() {
    var element, to_list;
    /* code here that gets element and to_list */

    // Modify the post to use a callback and the "text" data type
    $.post($(F).attr('action'), $(F).serialize(), handleMove, "text");

    // Here's the callback
    function handleMove(data) {
        eval(data);
    }
}

This works because eval is very special and it executes in the scope in which it's called (it's a bit magic in that way), and so the code in the text eval evaluates has access to all of the variables in scope where eval is called.

Going slightly off-topic, but I would recommend a data-based approach instead. Perhaps:

function doTheThing() {
    var element, to_list;
    /* code here that gets element and to_list */

    // Modify the post to use a callback and the "json" data type
    $.post($(F).attr('action'), $(F).serialize(), handleMove, "json");

    // Here's the callback
    function handleMove(data) {
        if (data.errorMessage) {
            /* ...show the error... */
        }
        else {
            moveNode(element, to_list);
        }
    }
}

...where your server either returns:

{"errorMessage": "Don't move it!"}

or

{"success": true}

or whatever makes sense in your environment. Heck, if it's really just "it worked" or "here's an error", you could just use a text protocol where "OK" meant okay and anything else was an error message (the internet is full of text-based protocols like that). I prefer more structure, but the point is you have options.

I would find that approach easier to maintain. When you start passing code back and forth between layers, code relying on knowing the names of in-scope variables, it seems like a major close-coupling issue.

T.J. Crowder
'eval' is almost always a bad idea.
Matthew Wilson
This should already be happening though, with a datatype of `"script"`: http://github.com/jquery/jquery/blob/master/src/ajax.js#L669
Nick Craver
This is not for a public site. So what would be your preferred method? JSON? My thoughts were that "script" was already doing this.
Dex
@Matthew: I agree wholeheartedly. There was a very big missing "n't" in my first sentence! It read "but I would recommend it" when of course I meant "but I *wouldn't* recommend it". :-)
T.J. Crowder
@Dex: Yes, I would use data (JSON, XML, text, whatever) to transfer a message, rather than code, between the layers; I was adding that suggestion as you asked the question. :-) Transferring code in that way is a close-coupling issue. (Doesn't matter whether it's an internal app or a public website.)
T.J. Crowder
Going a bit off-topic, does using eval in callbacks a bad idea too? I am asking this because i use the jquery taconite plugin which is xml based. I have to use eval in the xml structure that is returned sometimes due to limitations of taconite itself.
Shripad K