Post request from AngularJS always generates 500 error

Hi,

I have tried several different ways to make a post request from an angular front end to a Slim route. As you can see from my route, I’m trying to insert some data from the body of a post request into the database. While I have tested the query statement, so I know that it works, every time I make a request to this route I get a 500 error. If I comment out the query, I don’t get the error. Thanks in advance for any thougts/ ideas. And, please don’t hesitate to let me know if you need more code.

$app->post('/api/message', function ($request, $response, $args) {

$body = $request->getParsedBody();
$username = $body['username'];
$message = $body['text'];
$ip = 'test';

$statement = $this->db->query("INSERT INTO messages
    VALUES (NULL, '{$username}', '{$message}', '{$ip}', NOW()");


echo $statement;

});

Hi

Firstly, what I would do is check your DB function. Naturally I can’t see what $this->db is so it could be a service layer, a gateway or a PDO instance, but one thing I would definitely be doing is making sure you use prepared statements (that code you have posted may be just for demo purposes though, I don’t know). So I would look at doing something like this (this is just for testing purposes):

// Set up a PDO instance or whatever as you would then...
// eg: $this->setPdo(new PDO(<connection details>));

try {
    $sql = "INSERT INTO messages VALUES (NULL, :username, :message, :ip, NOW()"
    $stmt = $this->getPdo()->prepare($sql);
    $stmt->bindParam(':username', $body['username']);
    $stmt->bindParam(':message', $body['text']);
    $stmt->bindParam(':ip', 'test');
    $stmt->execute();
} catch (\PDOException $pdoException) {
    // Do something with your error message, for now you could just:
    die($pdoException->getMessage());
}

By putting it in a try / catch block you should be able to catch the errors and see if it is DB related (which I would suspect) or something to do with Slim. Slim shouldn’t 500 on basic functionality like that unless something along the chain failed. Without seeing all of your code I couldn’t say for sure, but posting and updating DB is bread and butter for Slim. At least this way you can rule out any DB issues.

On another side note, you should also be making sure you sanitise the data you get in - but that’s just a security thing :wink:

let me know how you get on

It’s right what Crags said.
You can also override the slim Error Handler.

$container['errorHandler'] = function (\Slim\Container $container) {
    return function ($request, $response, $exception) use ($container) {
    
        return $response->withJson(['error' => $exception->getMessage()], 500);
    };
};

This is a “wrong” error handler, but you can use it as base for see the errors on screen while you’re developing.

THIS MUST NOT BE USED IN PRODUCTION! Use it as sample for build your own.

Thanks very much for the suggestions. @Crags, prepare must have been necessary because your solution is working with a slight syntax modification that I will include below in case anyone else finds this answer useful. Apparently, you have to pass a variable to the second parameter of bindParam(). Huge thanks!! :relaxed: And, yes, I will sanitize the data.

$body = $request->getParsedBody();
$ip = ‘test’;

try {
    $sql = "INSERT INTO messages VALUES (NULL, :username, :message, :ip, NOW())";
    $stmt = $this->db->prepare($sql);
    $stmt->bindParam(':username', $body['username']);
    $stmt->bindParam(':message', $body['text']);
    $stmt->bindParam(':ip', $ip);
    $stmt->execute();

} catch (PDOException $pdoException) {
    // Do something with your error message, for now you could just:
     echo 'exception reached';
}