Axios发布方法因Laravel的状态码500而失败

时间:2018-11-07 19:02:28

标签: php laravel forms vue.js axios

正如标题所述,当使用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">&times;</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',
  ),
)

非常感谢您提供任何见识和帮助!

1 个答案:

答案 0 :(得分:0)

由于@rickdenhaan和@adam的帮助,我发现控制器中的输出显示了数据库中的数据。尽管似乎有很多原因可以使您从Axios调用中得到500响应,但我的情况是我将不正确的数组传递给了调用,而该数据与表单数据无关,并且我也将表单中的数据绑定到了错误的数组。