4

Alright, this is probably super simple but I've been breaking my head over this all day and I cannot get it to work.

I have a page that displays a list of users from a mysql query. On this page it should also be possible to add users. To do this, I'm sending an AJAX call to process.php which does some validation and sends an error if there is one. If there is no error, I want AJAX to update the page.

The problem is, that if there are no errors (a user has been added), I want to return the updated userlist. This means storing the output of my getUsers(); function in an array, which isn't possible.

How can I achieve this?

p.s. I realise this is crappy code and I should be using OOP/PDO, but this isn't for a production environment and it works. So I'll leave it like this for the time being.

users.php

<article>
    <ul>
        <?php getUsers(); ?>
    </ul>
</article>

<form id="addUserForm">
    ...
    <input type="hidden" name="addUser">
</form>

$("#addUserForm").on("submit",function() {
    event.preventDefault();
    var data = $("#addUserForm").serialize();
        $.ajax({
            type: "POST",
            url: "process.php",
            data: data,
            dataType: "json",
            success: function(response) {
                if (response.success) {
                    $("article ul).html(response.data);
                } else {
                    $(".errorMessage).html("<p>" + response.error + </p>");
                }
            }
        });
});

functions.php

function getUsers()
{
    global $db;
    $query = mysqli_query($db, "SELECT * FROM users");
        while($row = mysqli_fetch_assoc($query))
        {
            echo "<li>" . $row["user_firstname"] . "</li>";
        }
}

function addUser($email, $password)
{
    global $db;
    $result = mysqli_query($db, "INSERT INTO users ... ");
        return $result
}

process.php

if (isset($_POST["addUser"]))
{

    ... // Serialize data

        if (empty ...)
        {
            $responseArray = ["success" => false, "error" => "Fields cannot be empty"];
            echo json_encode($responseArray);
        }

        // If user is successfully added to database, send updated userlist to AJAX
        if (addUser($email, $password))
        {
            $responseArray = ["success" => true, "data" => getUsers();];
            echo json_encode($responseArray)
        }
}
8
  • You can use a try/catch block to catch errors and do something with it if there's a PHP error. This will work for all but fatal PHP errors. Commented May 23, 2017 at 15:23
  • "This means storing the output of my getUsers(); function in an array, which isn't possible.". Why isn't it possible? You seem to be doing it already in your process.php sample. Commented May 23, 2017 at 15:30
  • I've left it in as an example of what I'm trying to do. The code doesn't work. Commented May 23, 2017 at 15:33
  • I didn't really get the problem. Just return an html string from getUsers instead of printing it directly in the function. Or return an array to have it in a structured variable. Commented May 23, 2017 at 15:33
  • what does "doesn't work", mean, exactly? A PHP error? A JS error? P.S. If you're only adding a user, why not just return the finished data for the added user? Then you could just append that to your existing list of users on the page, rather than refreshing the whole thing. That's basically what most CRUD APIs of this kind do, by convention. Commented May 23, 2017 at 15:33

4 Answers 4

2

Your getUsers() function is printing and not returning the data to json connstructor

function getUsers()
    {
        global $db;
        $query = mysqli_query($db, "SELECT * FROM users");
            while($row = mysqli_fetch_assoc($query))
            {
                echo "<li>" . $row["user_firstname"] . "</li>";
            }
    }

it has to be something like this

function getUsers()
{
    global $db;
    $query = mysqli_query($db, "SELECT * FROM users");
        $list = "";
        while($row = mysqli_fetch_assoc($query))
        {
            $list. = "<li>" . $row["user_firstname"] . "</li>";
        }
      return $list;
}

And there is a syntax error in the following line

 if (addUser($email, $password)

close it with ")"

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

1 Comment

The syntax error was caused by pasting it into the StackOverflow editor. Will take a look at your answer once I get home. Thanks.
1

You can capture the output of the getUsers function without changing the current behavior if that's what you're after. In the success output change

$responseArray = ["success" => true, "data" => getUsers();];
echo json_encode($responseArray)

to

ob_start();
getUsers();
$usersList = ob_get_clean();
$responseArray = ["success" => true, "data" => $usersList];
echo json_encode($responseArray)

What this does is captures the output and stores it into a varable $usersList which you can then return as a string.

You'd be better off returning the users as an array and dealing with generating the markup on the client side IMO, but that's up to you. This is just another way to get what you have working.

More information about php's output buffer here

1 Comment

Will take a look at your answer once I get home. Thanks.
1

Are you trying to get the error returned by ajax or you want to have custom error? (e.g. string returned by your php script). If you're referring to ajax error you should have this:

EDIT: Since you mentioned you want a custom error returned by process.php

Process.php

if (isset($_POST["addUser"]))
{

    ... // Serialize data

        if (empty ...)
        {
            $responseArray = ["success" => false, "error" => "Fields cannot be empty"];
            echo json_encode($responseArray);
        }

        // If user is successfully added to database, send updated userlist to AJAX
        if (addUser($email, $password))
        {
            $responseArray = ["success" => true, "data" => getUsers();];
            echo json_encode($responseArray)
        }else{
            echo 1;
        }

        //I added else echo 1;
}

Your ajax will be:

  $("#addUserForm").on("submit",function() {
        event.preventDefault();
        var data = $("#addUserForm").serialize();
            $.ajax({
                type: "POST",
                url: "process.php",
                data: data,
                dataType: "json",
                success: function(response) {
                    if(response != 1){
                        $("article ul").html(response.data);
                    }else{
                        alert('Custom error!');
                    }
                },
                error: function(jqXhr, textStatus, errorThrown){
                   console.log(errorThrown);
                }
             });
     });

BTW you're missing ) in your posted code if (addUser($email, $password))

2 Comments

I'm trying to return a custom error which is echo'd by process.php. Currently I'm actually using the $.ajax error: function by echo'ing header("HTTP/1.0 500"), but that seems to be an even worse solution than what I'm trying to do.
The syntax error was caused by pasting it into the StackOverflow editor. The problem is that this only shows a single custom error, and not something returned by PHP, correct?
-1

This is how I do:

try{dataObj = eval("("+response+")");}
catch(e){return;}
alert(dataObj->example_key);

1 Comment

Your Answer

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