I’m creating an authentication system that uses Slim 3 PHP on the back-end and Angular on the front-end. So far I’ve managed to have it so a user can fill out a form on the frontend and send a post request to the back-end to insert that data into a database table.
Angular Register Component:
this.Auth.postUserDetails(username, password).subscribe(data => { console.log(data, 'is what we received from the backend:'); });
Angular Authentication Service:
postUserDetails(username, password) { return this.http.post('/api/achievement-forum-api/src/public/register', {username, password}); }
But on the back-end I have some form validation that produces some messages when say a password is less than 8 characters, which is in the form of a class that extends PHP’s LogicException class.
use Throwable; class InvalidFormData extends LogicException { public function __construct($message = "Password must be at least 8 characters", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); } }
This InvalidFormData is thrown when validation fails in the constructor of the Password class which is where validation takes place for passwords:
public function __construct(string $tainted_password) { $cleaned_password = filter_var($tainted_password, FILTER_SANITIZE_STRING); if ($this->isTooShort($cleaned_password)) throw new InvalidFormData(); $this->password = $cleaned_password; }
Then finally in the controller class we try to register a user but if we catch an InvalidFormData exception we extract the produced message.
public function registerUser($request, $response) { $tainted_username = $request->getParsedBody()['username']; $tainted_password = $request->getParsedBody()['password']; try { $this->authenticationService->registerUser($tainted_username, $tainted_password); } catch(InvalidFormData $e) { var_dump($e→getMessage()); //shows the message in the browsers console } }
Question:
What I would like to do is pass this message back to the Angular front-end and display it on the form so a user is able to see why they failed validation.
I’ve read through Slim 3’s response documentation but I’m not sure If I would have to send this message back as a Slim response, and if so how would I capture this within Angular? My first thought was I might need a get request within angular to get the message, but I’m sure there is a way to do it within the original post request.
I have read some of the Angular documentation and it seems I need to do something in the subscribe method but I’m not really sure what.
Hopefully someone could show me some some code examples of this process. How would I create a Slim 3 response containing the message and how might I capture this in Angular?
Advertisement
Answer
set in src/routes.php
:
$app->post( '/api/achievement-forum-api/src/public/register', function( Request $request, Response $response, array $args ) { $body = $request->getParsedBody(); // probably $body = [ "username" => "user name", "password" => "pass word" ] /* Do validation stuff here */ /* Depending of your validation results, set $status = something like 0 or 1... */ /* Depengind of your $status, set $message = "string to be displayed" */ /* Need to return data? $data = [ ... ] */ return $response->withJson( [ "status" => $status, "message" => $message, "data" => $data ] ); } );
The response layout was inspired on Instagram API (https://www.instagram.com/developer/endpoints/)
I have no contact with Angular for some years, but I think you have to do something like postUserDetails( params, here ).map(res=> res.json())
or another “responseHandler” method from the version of Angular you’re using.
I’m use to do it with fetch API
(https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch) or axios
(https://github.com/axios/axios) in my projects