2

I am trying to run a function to generate the url used in a jQuery ajax POST request, but it seems the url parameter can only be a string... Here is the code, note the function in the url parameter of the ajax call:

//chained code upstairs...
.bind("create.jstree", function (e, data) {
    $.ajax({
        //"/project/<%= locals.project.handle %>/mkdir/<%=locals.filepath%>",
        //"http://127.0.0.1/project/datanotes/mkdir/lolada/lolada_subdir",
        type : "POST",
        url :   function(data){
            var url = "<%= locals.request.db.baseURI + "/project/" + locals.project.handle + "/mkdir" %>";
            if(data.rslt.obj.attr("id") != null){
                url = url + "/" + data.rslt.obj.attr("id");
            }
            return url;
        },
        data : {
            "title" : data.rslt.name,
            "type" : data.rslt.obj.attr("rel")
        },
        success: function (r) {
            if(r.status) {
                $(data.rslt.obj).attr("id", "node_" + r.id);
            }
            else {
                $.jstree.rollback(data.rlbk);
            }
        },
        failure : function (r) {
            $.jstree.rollback(data.rlbk);
        }
    });
})

The url parameter is interpreted as a string and not evaluated, as the debug log is the following:

GET /project/datanotes/browse/children 200 369ms - 2b
POST /project/function%20(data)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20url%20=%20%22http://127.0.0.1:3000/project/datanotes/mkdir%22;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(data.rslt.obj.attr(%22id%22)%20!=%20null)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20url%20=%20url%20+%20%22/%22%20+%20data.rslt.obj.attr(%22id%22);%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20url;%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D 404 5ms

Can you help me circunvent the problem? Thanks!

2
  • 4
    Not sure if you can do this or not (what you're trying), but why not run the function right before the AJAX call, assign it to a variable, then use that? Commented Sep 26, 2013 at 13:05
  • Exactly, that is the best solution, thanks! Commented Sep 26, 2013 at 13:18

2 Answers 2

9

You are passing the function, not executing it and passing the result. You could use an immediately invoked function:

url: (function () {
    var url = "<%= locals.request.db.baseURI + " / project / " + locals.project.handle + " / mkdir " %>";

    if (data.rslt.obj.attr("id") != null) {
        url = url + "/" + data.rslt.obj.attr("id");
    }

    return url;
})(),

Simple demo: http://jsfiddle.net/yS6rn/

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for taking the time to explain the immediately invoked function. Works well and is something I did not know :-)
Although I would never consider using this technique to solve this specific circumstance (as it adds unneeded complexity) +1 for coolness :)
I would tend to agree.. in this case, it's probably not necessary. But it offers a way to make the asker's attempted solution work, and IIFE's are a good think to know about.
4

You were expecting a function to be evaluated when only a string was required. Why overcomplicate it? Just calculate the URL before the AJAX call (but still inside the binding function).

//chained code upstairs...
.bind("create.jstree", function (e, data) {
    var url = "<%= locals.request.db.baseURI + " / project / " + locals.project.handle + " / mkdir " %>";

    if (data.rslt.obj.attr("id") != null) {
        url = url + "/" + data.rslt.obj.attr("id");
    }

    $.ajax({
        //"/project/<%= locals.project.handle %>/mkdir/<%=locals.filepath%>",
        //"http://127.0.0.1/project/datanotes/mkdir/lolada/lolada_subdir",
        type: "POST",

        url: url,

        data: {
            "title": data.rslt.name,
                "type": data.rslt.obj.attr("rel")
        },
        success: function (r) {
            if (r.status) {
                $(data.rslt.obj).attr("id", "node_" + r.id);
            } else {
                $.jstree.rollback(data.rlbk);
            }
        },
        failure: function (r) {
            $.jstree.rollback(data.rlbk);
        }
    });
})

2 Comments

You are right, simple is always better and I will take your approach; however, the immediately invoked function was a new thing for me, and thus I will accept the other answer as it taught me something new and it solves the problem also. I will upvote nonetheless, thanks!
That's cool... I was impressed by it too. All functions in Javascript are apparently just strings... Opens up some interesting possibilities for self-modifying code! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.