0

I'm using jQuery $.ajax to add elements on-the-fly to my database.

The server-side returns the ID of the element recently added, and I want to capture that in my done event block.

        if(!key) {
            $.ajax({
                url: "/tags/add",
                type: "GET",
                data: {tagName:value}
            }).done(function(data){
                key = data;
            });
        }

/tags/add returns:

return new Response($tags[0]->getId(), 200, array('Content-Type' => 'text/html'));

where Response is framework specific.

If I go to the URL /tags/add?tagName=123

it will attempt to add that tag to the database if it doesn't exist. If it is succesful, it will return its id.

In the example above, in returns 63

but the done function doesn't seem to be catching that 63 (or whatever the number is)

Here's the catch.

Let's assume the tag dogs doesn't exist:

1) /tags/add?tagName=dogs will add dogs to the database, and will return ID 64

2) If I do console.log(data) in the first line inside the done event block, it will log 0 (default ID when the tag doesn't exist)

3) If I try to add dogs tag again to the database, /tags/add?tagName=dogs will see that dogs already exists, and will only return its id (64)

4) Then console.log(data) kicks in again, and it logs 64

Any idea why is that happening?

ILikeTacos
  • 17,464
  • 20
  • 58
  • 88
  • The value of `data` will be the response from your server; if that's not what you're expecting then it sounds like the issue is with the server-side code. – Anthony Grist Jun 05 '13 at 14:24
  • That's what I thought too, but if I navigate to the URL directly the server-side response is correct. – ILikeTacos Jun 05 '13 at 14:25
  • 1
    If your tagname doesn't exists, it is supposed to return new inserted ID or 0? I don't understand where is your problem here – A. Wolff Jun 05 '13 at 14:29
  • @roasted It's supposed to return the ID of the newly inserted row, and does so when navigating to the URL directly. Calling the URL via an AJAX request returns `0` incorrectly the first time (when the new row is inserted), but returns the correct ID on subsequent calls. That's how I'm interpreting the question, but took me a few reads to get there. – Anthony Grist Jun 05 '13 at 14:30
  • @AnthonyGrist that's right, sorry for wording incorrectly the question. – ILikeTacos Jun 05 '13 at 14:31
  • @AlanChavez Not sure what to tell you; the jQuery looks fine, and the value of `data` will be the server response. Can you step through the server side code and see what's happening differently when doing it via AJAX? – Anthony Grist Jun 05 '13 at 14:31
  • @AnthonyGrist so ya, seems to be a server side issue – A. Wolff Jun 05 '13 at 14:32
  • I already found the error, it wasn't server side... the problem was the asynchronous nature of ajax, for my snippet to work ajax had to work synchronously. – ILikeTacos Jun 05 '13 at 14:42

1 Answers1

0

The problem was with the asynchronous nature of ajax.

all I needed to do to capture the server response correctly outside the done block was to set async to false.

    if(!key) {
        $.ajax({
            async: false,
            url: "/tags/add",
            type: "GET",
            data: {tagName:value}
        }).done(function(data){
            key = data;
        });
    }
ILikeTacos
  • 17,464
  • 20
  • 58
  • 88
  • `async: false` is _never_ the right answer. It's not even supposed to work with `.done` deferred methods. – Alnitak Jun 05 '13 at 14:50
  • I understand the consequences of async: false, basically if the server never responds my script will wait until the server does. – ILikeTacos Jun 05 '13 at 14:52
  • yes, pretty much. There are always ways around this that don't involve using `return`. – Alnitak Jun 05 '13 at 14:53
  • it would be really helpful if you point me to the right direction :) – ILikeTacos Jun 05 '13 at 14:54
  • See http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call I always use the "deferred" object syntax myself. – Alnitak Jun 05 '13 at 14:55