正如标题所述,当使用Vue尝试将表单数据传递给我的Laravel控制器时,Axios发布失败。我见过很多人遇到这个问题,但是没有一个解决方案对我有用。我发现500状态代码有点含糊。深入研究我遇到的问题,我发现主要问题是我的数据库中有一个不能为null的字段,这是我在laravel.log中遇到的错误
[2018-11-07 18:45:21] development.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'string_date' cannot be null (SQL: insert into `action_logs` (`string_date`, `user_id`, `company_name`, `name`, `communication_type`, `contact`, `status`, `action_item`, `activity_key`, `assigned_to`, `updated_at`, `created_at`) values (, 1, , , , , , , 1,2, no one, 2018-11-07 18:45:21, 2018-11-07 18:45:21)) {"userId":1,"email":"frank@*******.com","exception":"[object] (Illuminate\\Database\\QueryException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'string_date' cannot be null (SQL: insert into `action_logs` (`string_date`, `user_id`, `company_name`, `name`, `communication_type`, `contact`, `status`, `action_item`, `activity_key`, `assigned_to`, `updated_at`, `created_at`) values (, 1, , , , , , , 1,2, no one, 2018-11-07 18:45:21, 2018-11-07 18:45:21))
这似乎表明表单中的数据根本没有传递,或者控制器由于某种原因无法访问数据。我不太确定为什么,但是我是根据之前为我工作的示例构建的。我尝试了一个建议,发现默认情况下Axios发送了一个JSON对象。我尝试在Laravel控制器中进行相应的解析,但是并不能解决问题。我已经检查过以确保csrf令牌正常工作。我能够记录来自控制器的消息,因此我知道Vue正在查找路由。但是,我正在呼叫我的路线,试图传递公司名称,例如:
Route::post('/action-log/{url}', 'ActionLogController@store');
我还没有尝试删除它,但这仅仅是因为我可以看到它仍按预期方式调用store方法。这是我的Vue组件中的相关代码:
<template>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th><a id="sortby-date" class="action-nav" href="?sortby=date&sortdirection=desc">Date</a></th>
<th><a id="sortby-company" class="action-nav" href="?sortby=company&sortdirection=desc">Company</a></th>
<th><a id="sortby-name" class="action-nav" href="?sortby=name&sortdirection=desc">Name</a></th>
<th><a id="sortby-communication-type" class="action-nav" href="?sortby=communication-type&sortdirection=desc">Communication Type</a></th>
<th><a id="sortby-contact" class="action-nav" href="?sortby=contact&sortdirection=desc">Contact</a></th>
<th><a id="sortby-subject" class="action-nav" href="?sortby=subject&sortdirection=desc">Subject</a></th>
<th><a id="sortby-action" class="action-nav" href="?sortby=action&sortdirection=desc">Comment/Action Item</a></th>
<th>Archive</th>
<!-- check if admin?? -->
<th><a id="sortby-assigned-to" class="action-nav" href="?sortby=date&sortdirection=desc">Assigned To</a></th>
<!-- /check if admin?? -->
</tr>
</thead>
<tbody v-if="actions.length > 0">
<tr v-for="action in actions" :key="action.id">
<td>
{{ action.string_date }}
</td>
<td>
{{ action.company_name }}
</td>
<td>
{{ action.name }}
</td>
<td>
{{ action.communication_type }}
</td>
<td>
{{ action.contact }}
</td>
<td>
{{ action.status }}
</td>
<td>
{{ action.action_item }}
</td>
<td>
<input type="checkbox" :id="'archive-' + action.id" class="archive" :name="'archive-' + action.id">
</td>
<td :id="'record-' + action.id" class="assigned-to">
{{ action.assigned_to }}
</td>
</tr>
</tbody>
</table>
<!-- Button trigger modal -->
<p id="add-action" style="text-align: center;">
<button id="action-log-modal" type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#addAction">
Add New Action Log
</button>
</p>
<!-- Modal -->
<div class="modal fade" id="addAction" tabindex="-1" role="dialog" aria-labelledby="addActionTitle" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<form id="action-log-form" class="" name="action-log-form" role="form" method="post" :action="this.url" enctype="multipart/form-data">
<div class="modal-content">
<input type="hidden" name="_token" :value="csrf">
<div class="modal-header">
<h5 class="modal-title" id="addActionTitle">Add Action Log</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- Errors -->
<div class="alert alert-danger" v-if="createAction.errors.length > 0">
<p>
<strong>Whoops!</strong> Something went wrong.
</p>
<p></p>
<ul>
<li v-for="error in createAction.errors">
{{ error }}
</li>
</ul>
</div>
<div class="form-group">
<label for="date">Date</label>
<input id="date" class="form-control form-control-sm" name="date" type="text" value="01/01/1970" placeholder="MM/DD/YYYY" required>
</div>
<div class="form-group">
<label for="company">Company</label>
<input type="text" id="company" class="form-control" name="company" :value="this.companyName" :placeholder="this.companyName" @keyup.enter="store" required readonly>
</div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" :value="this.userFullName" :placeholder="this.userFullName" @keyup.enter="store" required readonly>
</div>
<div class="form-group">
<label for="communication-type">Communication Type</label>
<select id="communication-type" name="communication_type" class="custom-select mr-sm-2" @change="store" v-model="actions.communication_type">
<option value="not-selected">Choose...</option>
<option value="phone">Phone</option>
<option value="email" selected>Email</option>
<option value="in-person">In Person</option>
<option value="fax">Fax</option>
<option value="customer-site">Customer Site</option>
</select>
</div>
<div class="form-group">
<label for="contact">Contact</label>
<input type="text" id="contact" class="form-control form-control-sm" name="contact" value="test contact" @keyup.enter="store" v-model="actions.contact" required>
</div>
<div class="form-group">
<label for="current-status">Current Status</label>
<input type="text" id="current-status" class="form-control form-control-sm" name="current_status" value="test current status" @keyup.enter="store" v-model="actions.current_status" required>
</div>
<div class="form-group">
<label for="action-item">Action</label>
<textarea id="action-item" class="form-control" name="action_item" rows="3" @keyup.enter="store" v-model="actions.action_item">test action</textarea>
</div>
<div class="form-group">
<label>Product Document</label>
<div class="custom-file">
<input type="file" id="productDocument" class="custom-file-input" name="product_document">
<label class="custom-file-label" for="productDocument">Choose file</label>
</div>
</div>
<div class="form-group">
<label>Test Data</label>
<div class="custom-file">
<input type="file" id="testData" class="custom-file-input" name="test_data">
<label class="custom-file-label" for="testData">Choose file</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" @click="store">Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['companyName', 'userFullName'],
data() {
return {
actions: [],
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
createAction: {
errors: [],
date: '',
company: '',
name: '',
communication_type: '',
contact: '',
current_status: '',
action_item: ''
},
url: ''
}
},
mounted() {
// console.log('Action Log Mounted.');
this.getActions();
// updates the date when changed in add new action form
$('#date').on('changeDate', () => { this.actions.date = $('#date').val() });
},
methods: {
getActions() {
//get company name to pass to request
var currentLocation = window.location.href;
// console.log(currentLocation);
var companyName = currentLocation.split('/');
companyName = companyName[companyName.length - 1];
let url = '/action-log/' + companyName;
this.url = url;
// console.log("just stored this.url with " + this.url);
//get actions
axios.get(url)
.then(response => {
this.actions = response.data;
this.actions.company = this.companyName;
this.actions.name = this.userFullName;
})
.catch(error => {
console.log(error);
});
},
store() {
let url = window.location.href;
url = url.replace('home', 'action-logs');
console.log(this.url);
this.persistAction(
'post',
// '/' + this.url,
this.url,
this.actions,
'#addAction'
);
},
persistAction(method, uri, form, modal) {
// console.log("method = " + method);
// console.log("uri = " + uri);
// console.log("form = " + form);
// console.log("modal = " + modal);
console.log("date = " + form.date);
console.log("company = " + form.company);
console.log("name = " + form.name);
console.log("contact = " + form.contact);
console.log("current_status = " + form.current_status);
console.log("action_item = " + form.action_item);
form.errors = [];
axios[method](uri, form)
.then(response => {
this.getActions();
// console.log('seemingly successful');
form.date = '';
form.company = '';
form.name = '';
form.communicationType = 'not-selected';
form.contact = '';
form.currentStatus = '';
form.actionItem = '';
form.productDocument = '';
form.testData = '';
form.errors = [];
})
.catch(error => {
if (typeof error.response.data === 'object') {
form.errors = _.flatten(_.toArray(error.response.data));
}
else {
form.errors = ['Something went wrong. Please try again.'];
}
console.log('there was an error: ' + error);
});
}
}
}
</script>
以及我想从控制器中使用的代码:
public function store(Request $request)
{
// get company being viewed
$companyViewing = explode('/', $request->path());
$companyViewing = $companyViewing[count($companyViewing) - 1];
$data = $request->json()->all();
// Log::debug($request);
// Log::debug($data);
$action = new ActionLog();
$action->string_date = $request->date;
$action->user_id = Auth::user()->id;
$action->company_name = $request->company;
$action->name = $request->name;
$action->communication_type = $request->communication_type;
$action->contact = $request->contact;
$action->status = $request->current_status;
$action->action_item = $request->action_item;
$client_id = Company::where('name', '=', $companyViewing)->first(['id']);
$action->activity_key = '1,' . $client_id->id;
if($request->assigned_to !== null) {
$action->assigned_to = $request->assigned_to;
}
else {
$action->assigned_to = "no one";
}
$action->save();
$actions = '';
if(Auth::user()->role == 'admin') {
$actions = ActionLog::where('user_id', '=', Auth::user()->id)
->where('activity_key', '=', '1,' . $client_id->id) //return only relevant activities between AST and client, even if the client is AST!
->orderBy('created_at', 'desc')
->get();
}
else {
$actions = ActionLog::where('user_id', '=', Auth::user()->id)
->where('activity_key', '=', '1,' . $client_id->id)
->orderBy('created_at', 'desc')
->get(['id', 'string_date', 'company_name', 'name', 'communication_type', 'contact', 'status', 'action_item']);
}
return response()->json(['success' => 'Data is successfully added', 'actions' => $actions, 'role' => Auth::user()->role]);
}
编辑:这是当我为来自vue的表单数据调用console.log时的输出。
date = 01/01/1970 app.js:47573:13
company = AST app.js:47574:13
name = Frank app.js:47575:13
contact = zxcv app.js:47576:13
current_status = test app.js:47577:13
action_item = asdf app.js:47578:13
there was an error: Error: Request failed with status code 500
当我调用Log :: debug($ request-> all())和Log :: debug($ data)时,在laravel.log中输出。这两个调用都给出了相同的信息数组,实际上与我发布的内容无关。这些是数据库表中已经存在的当前记录,这似乎很奇怪,因为我正试图从表单中获取数据。
[2018-11-07 19:50:14] development.DEBUG: array (
0 =>
array (
'id' => 4,
'user_id' => 1,
'company_name' => 'AST',
'name' => 'Frank',
'communication_type' => 'email',
'contact' => 'asdf',
'status' => 'fdas',
'action_item' => 'asdf',
'assigned_to' => 'no one',
'string_date' => '11/11/2018',
),
1 =>
array (
'id' => 3,
'user_id' => 1,
'company_name' => 'AST',
'name' => 'Frank',
'communication_type' => 'email',
'contact' => 'fdas',
'status' => 'fda',
'action_item' => 'fdas',
'assigned_to' => 'no one',
'string_date' => '10/24/2018',
),
2 =>
array (
'id' => 2,
'user_id' => 1,
'company_name' => 'AST',
'name' => 'Frank',
'communication_type' => 'fax',
'contact' => 'asdf',
'status' => 'asdf',
'action_item' => 'asdf',
'assigned_to' => 'rob',
'string_date' => '10/10/2018',
),
3 =>
array (
'id' => 1,
'user_id' => 1,
'company_name' => 'AST',
'name' => 'Frank',
'communication_type' => 'in-person',
'contact' => 'asdf',
'status' => 'asdf',
'action_item' => 'asdf',
'assigned_to' => 'bob',
'string_date' => '10/02/2018',
),
)
非常感谢您提供任何见识和帮助!
答案 0 :(得分:0)
由于@rickdenhaan和@adam的帮助,我发现控制器中的输出显示了数据库中的数据。尽管似乎有很多原因可以使您从Axios调用中得到500响应,但我的情况是我将不正确的数组传递给了调用,而该数据与表单数据无关,并且我也将表单中的数据绑定到了错误的数组。