将 Slim 3 异常响应传递给 Angular 应用程序

Passing a Slim 3 Exception response to an Angular application

我正在创建一个在后端使用 Slim 3 PHP 并在前端使用 Angular 的身份验证系统。到目前为止,我已经设法让用户可以在前端填写表格并向后端发送 post 请求以将该数据插入数据库 table.

Angular 注册组件:

this.Auth.postUserDetails(username, password).subscribe(data => {
  console.log(data, 'is what we received from the backend:');
  });

Angular 身份验证服务:

postUserDetails(username, password) {
    return this.http.post('/api/achievement-forum-api/src/public/register',
      {username, password});
  }

但是在后端我有一些表单验证,当说密码少于 8 个字符时,它会产生一些消息,它的形式是扩展 PHP 的 class' s 逻辑异常 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);
    }

}

当在密码 class 的构造函数中验证失败时抛出此 InvalidFormData,这是对密码进行验证的地方:

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;
}

然后最后在控制器 class 中,我们尝试注册一个用户,但如果我们捕捉到 InvalidFormData 异常,我们将提取生成的消息。

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
    }
}

问题:

我想做的是将此消息传递回 Angular 前端并将其显示在表单上,​​以便用户能够看到他们验证失败的原因。

我已经通读了 Slim 3 的响应文档,但我不确定是否必须将此消息作为 Slim 响应发回,如果是这样,我将如何在 Angular 中捕获它?我的第一个想法是我可能需要 angular 内的获取请求来获取消息,但我确信在原始 post 请求内有一种方法可以做到这一点。

我已经阅读了一些 Angular 文档,似乎我需要在订阅方法中做一些事情,但我不太确定是什么。

希望有人可以向我展示此过程的一些代码示例。我将如何创建包含消息的 Slim 3 响应以及如何在 Angular 中捕获它?

设置于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 ] );
} );

响应布局的灵感来自 Instagram API (https://www.instagram.com/developer/endpoints/)

我已经好几年没有接触过 Angular,但我认为你必须做一些类似 postUserDetails( params, here ).map(res=> res.json()) 或 Angular 版本的其他 "responseHandler" 方法你正在使用。

我习惯在我的项目中使用 fetch API (https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch) or axios (https://github.com/axios/axios)