1

I have a PHP function server-side that looks like this:

function isHandleAvailable($displayname) {
    $res = user::getRow(
        "SELECT `id` FROM `users` WHERE `displayname` = :displayname",
        array(':displayname' => $displayname)
    );
    if ($res) {
        $res = 'Got a row!';
    } else {
        $res = 'No row :(';
    }

    echo $res;
}

and it's used to determine if a display name is already being used on the site. This function is called by the following JavaScript:

function checkHandleAvailability(displayName, callback) {
    $.ajax({
        type: 'POST',
        url: '/users/isHandleAvailable',
        data: { displayname: displayName }
    })
        .done(function(data, textStatus, jqXHR) {
            isHandleAvailable = data;
        })
        .fail(function() {
            isHandleAvailable = false;
        })
        .always(function() { callback(); });
}

however, the data and jqXHR.responseText are both an empty string. I know the PHP code is working because I put it into a basic test.php page and got the expected strings echoed to the screen.

Why isn't the result getting back to the .done function?

Mike Perrenoud
  • 63,395
  • 23
  • 143
  • 222
  • Could you post which MVC framework you're using? Is it a custom thing? – Matt Kantor May 04 '13 at 02:59
  • I wouldn't use 404 in this case. [HTTP status codes/headers](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) can often be a very expressive way to communicate things like this, but if you read the description for 404, it doesn't really apply to your situation. If instead you were going to try to create a new user without checking first and wanted to tell the client that there was a username collision, 403 might be a good status. – Matt Kantor May 04 '13 at 03:05
  • Return your data as `JSON`, and get it in your javascript code as an object. I think that you are getting an `string` and you get empty string, because you have `false` value in your function, that PHP converts it to boolean that becomes to empty string (`''`). –  May 04 '13 at 03:10
  • I just noticed your edits. Could you try opening up Web Inspector/Firebug/your dev tools of choice and inspecting the network traffic while triggering the AJAX request? There you'll be able to look at the raw request/response, which usually helps narrow down these kinds of problems. – Matt Kantor May 05 '13 at 16:42

2 Answers2

1

You'll need to output the value, just like non-AJAX webpage content.

If you want to communicate structured/typed data to the client (as opposed to some text or HTML), you should probably use JSON. PHP comes with a handy json_encode function to serialize PHP values to JSON.

The way to do the output might differ depending on your framework and whether you think this should count as a "view", but a simple way would be to just echo what you want to hand off to the client right from the controller method.

You should also set the Content-type header to application/json to let the client know you're sending JSON over the wire. Again, the specifics of where/how you should do that depend on your framework and architectural preferences. The easy but possibly less maintainable way is to just set the header in the controller method.

So, putting that all together, try this:

function isHandleAvailable($displayname) {
    $handleIsAvailable = user::getRow(
        "SELECT `id` FROM `users` WHERE `displayname` = :displayname",
        array(':displayname' => $displayname)
    ) == null;

    // This has to happen before any output.
    header('Content-type: application/json');

    echo json_encode($handleIsAvailable);
}
Community
  • 1
  • 1
Matt Kantor
  • 1,593
  • 1
  • 17
  • 35
0

Try to add the option "dataType: 'string'", by default $.ajax try to guess the content of the response and maybe this time is wrong.

But, as suggested by Matt Kantor, the best practice is to encode your response with some structured protocol like JSON or XML.

Mangiucugna
  • 1,662
  • 1
  • 14
  • 23