angular - 加载资源失败:服务器在 Angular-7 和 Laravel-5.8 中响应状态为 422(无法处理的实体)
问题描述
我正在使用 Angular-7 作为前端和 Laravel-5.8 开发客户端门户应用程序。我正在使用 Larave Spatie 进行用户管理。我有这三个表:
拉拉维尔:
CREATE TABLE `client` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`client_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`client_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `users` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`client_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
从上面的表格中,我有两个类:用户和客户。
每个用户都属于一个客户,但不超过一个。
client 中的 client_id 也是主键。
用户控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\User;
use App\Client;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use App\Notifications\SignupActivate;
use Avatar;
use Storage;
use App\Guardian;
class UsersController extends Controller
{
public function update(Request $request, $id)
{
if(!Auth::user()->hasPermissionTo('Edit Users') && !Auth::user()->id==$id)
return response()->json([ "message" => 'User do not have permission'], 401);
$rules = [
'name' => 'required|min:2',
'client_id' => 'required'
];
$this->validate($request, $rules);
$user = User::findOrFail($id);
if($request->role){
foreach($user->roles as $role)
$user->removeRole($role);
foreach($request->role as $role)
$user->assignRole($role);
}
$user->name = $request->name;
$user->save();
return response()->json(['data' => $user], 201);
}
}
客户端控制器.php
public function clientAll(){
return response()->json(Client::all());
}
api.php
Route::group([
'middleware' => 'auth:api'
], function () {
Route::get('users/profile', 'UsersController@profile');
Route::resource('users', 'UsersController', ['only' => ['index', 'show', 'store', 'update', 'destroy']]);
Route::post('users/pause', 'UsersController@pause');
});
Route::group([
'middleware' => 'auth:api'
], function () {
Route::get('client/clientall', 'ClientController@clientAll');
Route::resource('client', 'ClientController', ['only' => ['index', 'show', 'store', 'update', 'destroy']]);
});
在更新用户日期期间,我希望有一个填充了 client_id/client_name 的下拉选择选项。这样我就可以使用 client_id 更新用户表。
角
用户.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ApiService } from '../../../shared/services/api.service';
import { SnotifyService } from 'ng-snotify';
import { Router, ActivatedRoute } from '@angular/router';
import {NgbPaginationConfig} from '@ng-bootstrap/ng-bootstrap';
import { TokenService } from '../../../shared/services/token.service';
import { RolesCheckService } from 'src/app/shared/services/roles-check.service';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
users = null; //Store Users Data
roles = null; //Store all roles Data
clients = null;
public error = {
'role' : null,
'email' : null,
'client_id' : null,
'name' : null,
'password' : null
};
//Form errors
keyword = null; //Current Search Keyword
pagination = { //Current Pagination data
'page' : '1',
'max' : '10'
}
role = null;
User = 'User';
data = { //User Update Data
"id" : null,
"name" : null,
"client_id" : null,
"role" : []
}
form = { //New User add Data
'name' : null,
'email' : null,
'client_id' : null,
'password' : null,
'password_confirmation' : null,
'role' : []
}
headers = { //Token for API Authorization
'Authorization' : this.token.get(),
'X-Requested-With' : 'XMLHttpRequest'
}
sortData = { //Current Sort Data
"col" : null,
"order" : null
}
isSuperAdmin = false;
constructor(private roleManage : RolesCheckService , private route : ActivatedRoute, private pg: NgbPaginationConfig, private token : TokenService, private http : HttpClient, private router : Router,private api : ApiService, private notify : SnotifyService) {
pg.boundaryLinks = true;
pg.rotate = true;
}
ngOnInit() {
console.log('isSuperAdmin: ' + this.roleManage.isSuperAdmin);
this.isSuperAdmin = this.roleManage.isSuperAdmin;
this.route.queryParams.subscribe(params => {
if(params['role']){
this.role = params['role'];
this.User = this.role;
} else {
this.User = 'User';
this.role = '';
}
})
this.notify.clear();
this.notify.info("Loading...", {timeout: 0});
if(this.keyword) {
this.api.get('users?search=' + this.keyword + '&page=' + this.pagination.page + '&sort=' + this.sortData.col + '&order=' + this.sortData.order + '&role=' + this.role, this.headers).subscribe(
data => this.datahandler(data),
error => { this.notify.clear(); console.log(error); this.notify.error(error.error.message); }
);
} else {
this.api.get('users?page=' + this.pagination.page + '&sort=' + this.sortData.col + '&order=' + this.sortData.order + '&role=' + this.role, this.headers).subscribe(
data => this.datahandler(data),
error => { console.log(error); this.notify.error(error.error.message); }
);
}
this.api.get('role', this.headers).subscribe(
data => { console.log(data); this.roles=data; },
error => { console.log(error); this.notify.clear(); this.notify.error(error.error.message); }
);
this.api.get('client/clientall', this.headers).subscribe(
data => this.clients = data,
error => { this.notify.error(error.error.message) }
);
}
datahandler(data){
console.log(data.data);
this.notify.clear();
this.users = data.data;
this.pagination.max = data.total;
}
//sort handler
sort(col){
console.log(col);
if(this.sortData.order=="asc" && this.sortData.col==col){
this.sortData.order = "desc"
} else if(this.sortData.order=="desc" && this.sortData.col==col){
this.sortData.order = null;
col = null;
} else {
this.sortData.order = "asc"
}
this.sortData.col = col;
this.ngOnInit();
}
//Paginate Handling
paginateClick(page){
console.log(page);
this.pagination.page = page;
this.ngOnInit();
}
//Serach Handling
search(){
this.ngOnInit();
}
//Pause or Active User Handling
pause(id){
this.notify.clear();
console.log(id);
var body = {
"id" : id
}
return this.api.post('users/pause', body, this.headers).subscribe(
data => {this.notify.info("Success", {timeout: 2000}); this.ngOnInit(); },
error => this.notify.error(error.message, {timeout: 0})
);
}
//User edit Handling
edit(id){
this.notify.clear();
this.data.name = null;
this.data.role = [];
this.api.get('users/'+id, this.headers).subscribe(
data => this.editDataHandler(data),
error => this.notify.error("User Not Found", {timeout: 0})
);
this.data.id = id;
var modal = document.getElementById('editModal');
modal.style.display = "block";
}
editDataHandler(data){
console.log(data);
this.data.name = data.name;
for(var i=0; i<data.roles.length; i++)
this.data.role.push(data.roles[i].name);
}
checkbox(event){
if(event.srcElement.checked){
this.data.role.push(event.srcElement.name);
} else {
var index =this.data.role.indexOf(event.srcElement.name);
this.data.role.splice(index, index+1);
}
console.log(this.data.role);
}
editsubmit(){
this.notify.clear();
this.notify.info("Wait...", {timeout: 0});
this.api.put('users/'+this.data.id, this.data, this.headers).subscribe(
data => {
this.notify.clear();
this.notify.info("User Updated Successfully", {timeout: 2000});
this.ngOnInit();
this.closeEditModal();
},
error => { this.notify.clear(); this.error = error.error.errors; }
);
}
closeEditModal(){
this.error = {
'role' : null,
'email' : null,
'client_id' : null,
'name' : null,
'password' : null
};
var modal = document.getElementById('editModal');
modal.style.display = "none";
}
//User delete Handling
delete(id){
this.notify.clear();
this.notify.warning('Are you sure you want to detele this User?', 'Delete User', {
timeout: 0,
showProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
buttons: [
{text: 'Yes', action: () => {
var headers = {
'Authorization' : this.token.get()
}
return this.api.delete('users/'+id, headers).subscribe(
data => {this.notify.info("Success", {timeout: 2000}); this.ngOnInit(); },
error => this.notify.error(error.message, {timeout: 0})
);
}, bold: false},
{text: 'No'}
]
});
}
//New User add Handling
add(){
this.notify.clear();
this.form.name = null;
this.form.email = null;
this.form.password = null;
this.form.password_confirmation = null;
this.form.role = [];
var modal = document.getElementById('addModal');
modal.style.display = "block";
}
checkboxAdd(event){
if(event.srcElement.checked){
this.form.role.push(event.srcElement.name);
} else {
var index =this.form.role.indexOf(event.srcElement.name);
this.form.role.splice(index, index+1);
}
console.log(this.form.role);
}
addModalSubmit(){
this.notify.clear();
this.notify.info("Wait...", {timeout: 0});
this.api.post('users', this.form, this.headers).subscribe(
data => {
this.notify.clear();
this.notify.info("User Added Successfully", {timeout: 2000});
this.ngOnInit();
this.closeAddModal();
},
error => { this.notify.clear(); this.error = error.error.errors; }
);
}
closeAddModal(){
this.error = {
'role' : null,
'email' : null,
'client_id' : null,
'name' : null,
'password' : null
};
var modal = document.getElementById('addModal');
modal.style.display = "none";
}
}
user.component.html
<!-- The Modal -->
<div id="addModal" class="modal" style="background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.4);">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)='closeAddModal()'>
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-danger" [hidden]="!error.role">
{{ error.role }}
</div>
<div class="alert alert-danger" [hidden]="!error.email">
{{ error.email }}
</div>
<div class="alert alert-danger" [hidden]="!error.name">
{{ error.name }}
</div>
<div class="alert alert-danger" [hidden]="!error.password">
{{ error.password }}
</div>
<form #editUserForm=ngForm>
<div class="form-group">
<label for="name">Name</label>
<input type="name" name="name" id="inputName" class="form-control" placeholder="Name" [(ngModel)]="form.name" required>
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required [(ngModel)]="form.email">
</div>
<div class="form-group">
<label for="name">Role</label>
<div *ngFor="let role of roles">
<input type="checkbox" name="{{ role.name }}" value="{{ role.name }}" (change)="checkboxAdd($event)"> {{ role.name }}
</div>
</div>
<div class="form-group">
<label for="name">Password</label>
<input type="password" name="password" id="inputPassword" [(ngModel)]="form.password" class="form-control" placeholder="Password" required>
</div>
<div class="form-group">
<label for="name">Password Confirmation</label>
<input type="password" name="password_confirmation" id="inputPasswordConfirm" [(ngModel)]="form.password_confirmation" class="form-control" placeholder="Re enter Password" required>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)='addModalSubmit()' [disabled]="!editUserForm.valid">Save changes</button>
<button type="button" class="btn btn-secondary" (click)='closeAddModal()'>Close</button>
</div>
</div>
</div>
当我单击提交按钮(保存更改)时,我收到此错误消息:
加载资源失败:服务器响应状态为 422(无法处理的实体)
当我在网络上查看开发者的工具时,我发现了这个错误信息:
我该如何解决这个问题?
解决方案
Controller
每当您要求验证请求并且此验证失败时,Laravel 都会返回 HTTP 错误 422 。update
您可以在以下几行的函数中使用此验证UserController
:
$rules = [
'name' => 'required|min:2',
'client_id' => 'required'
];
$this->validate($request, $rules);
因此,其中一项规则必须验证失败。幸运的是 LaravelMessageBag
会为你返回一大堆错误。如果您的Accepts
HTTP 错误设置为 json,它将是一个很好的人类可读响应。继续并打开您用于测试和查看网络响应的浏览器的开发人员工具。你会看到这样的东西:
{
"message": "The given data was invalid.",
"errors": {
"name": [
"The name must be at least 2 characters long."
]
}
}
这个验证错误的消息包会指出你的问题。
编辑:由于我们已将其范围缩小到 Angular 未能发送,client_id
因此有两种方法可以解决您的问题:
- 为 client_id 添加一个表单字段,该字段与您在更新调用中发送
client_id
的对象耦合:data
<div class="form-group">
<label for="name">Client</label>
<select [(ngModel)]="data.client_id">
<option *ngFor="let client of clients" [value]="client.id">
{{ client.name }}
</option>
</select>
</div>
- 把它当作概念证明,然后从那里弄清楚;)
editsubmit(){
this.data.client_id = 1;
this.notify.clear();
this.notify.info("Wait...", {timeout: 0});
this.api.put('users/'+this.data.id, this.data, this.headers).subscribe(
data => {
this.notify.clear();
this.notify.info("User Updated Successfully", {timeout: 2000});
this.ngOnInit();
this.closeEditModal();
},
error => { this.notify.clear(); this.error = error.error.errors; }
);
}
推荐阅读
- c++ - 当 QProcess 需要用户使用 Qt 输入时如何阅读
- c - 具有多个定义的嵌入式 C 和 AVR GCC 编译问题
- django - Superset Flask OAuth 客户端没有 redirect_uri
- php - 如何通过laravel中的group by子句对获取的数据实现循环?
- javascript - Javascript/Firestore: Uncaught (in promise) TypeError: firebase.firestore(...).collection(...).doc(...).collection(...).set is not a function
- python - pytest_bdd.exceptions.StepDefinitionNotFoundError 在 StepDefinition 中使用 parrs.re 时触发错误
- angular - 我应该订阅还是使用支持属性来更新组件中的依赖数据?
- python - 从 django 子进程调用 python,mysql not found 错误
- swift - 在选择器列表 SwiftUI 上添加搜索栏
- java - 在 .txt 文件中搜索字符串并获取 Java 中的行号和列号