質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

0回答

938閲覧

Laravel + Vue.js でControllerでget()にするとエラー

mikeko0901

総合スコア227

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2021/11/18 13:30

勉強も兼ねてLaravel8系とVue.jsで注文一覧ページを構築しています(管理画面)
Laravelはapiとして、SPAで構築しています。

注文番号(一部)を入力して検索ボタンをクリックして結果を表示するところで、以下のエラーが出ます。
イメージ説明

[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'length')"

イメージ説明

以下コードになります。

■OrderList.vue テーブル部分省略

<template> <div> <div class="content-header"> <div class="container-fluid"> <div class="row mb-2"> <div class="col-sm-6"> <h1 class="m-0 text-dark">注文一覧</h1> </div> <div class="col-sm-6"> <ol class="breadcrumb float-sm-right"> <li class="breadcrumb-item"><a href=/admin/>Home</a></li> <li class="breadcrumb-item active">Order</li> </ol> </div> </div> <order-search @aaa="search($event)" @set_order_id="setSearchOrderId($event)" @set_name="setSearchName($event)" > </order-search> <span class=""> <button type="button" class="btn bg-gradient-primary btn-xs download_btn" @click="listDownload">Download</button> </span> </div> </div> <section class="content"> <div class="container-fluid"> <div class="card"> <div class="table-responsive mb-4 p-4"> <paginate :page-count="getPageCount" :page-range="3" :margin-pages="2" :click-handler="clickCallback" :prev-text="'‹'" :next-text="'›'" :container-class="'pagination mb-4 float-left'" :page-class="'page-item'" :page-link-class="'page-link'" :prev-link-class="'page-link'" :next-link-class="'page-link'"> </paginate> <table class="table table-hover text-sm" id="tbl_product"> <thead> <tr> <th></th> <th>注文番号</th> </tr> </thead> <tbody> <tr v-for="(order, index) in getItems" :key="index"> <td> <router-link v-bind:to="{name: 'order.detail', params: {order_id: order.id}}"> <button type="button" class="btn btn-pill btn-block btn-warning">詳細</button> </router-link> </td> <td>{{ order.order_id }}</td> </tr> </tbody> </table> </div> </div> </div> </section> </div> </template> <script> import OrderSearch from './OrderSearch.vue'; import Util from '../util'; export default { names: 'OrderList', components: { 'order-search': OrderSearch, }, props: { csrf: { type: String, }, }, data() { return { orders: [], search_order_id: "", search_name: "", names: [ {label: "管理者", value: "管理者"}, {label: "一般", value: "一般"}, ], //pagenateで追加 par_page: 10, current_page: 1 } }, mounted() { axios.get('/api/orders') .then((response) => { this.orders = response.data; }); }, computed: { getItems: function() { //pagenateで追加 let current = this.current_page * this.par_page; let start = current - this.par_page; return this.orders.slice(start, current); }, getPageCount: function() { //pagenateで追加 console.log("getPageCount:" + this.orders.length); return Math.ceil(this.orders.length / this.par_page); }, getTotalPrice: function(price, buy_num) { return price * buy_num; } }, methods: { search: function(value) { const url = '/api/orders_search'; let params = new FormData(); params.append('search_order_id', value.id ?? ''); params.append('search_name', value.name ?? ''); console.log('ajax前のparams:' + params); axios.post(url, params) .then(response => { console.log("検索結果:" + response); this.orders = response.data.data; }) .catch(error => { console.log(error); }); }, setSearchOrderId: function(value) { this.search_order_id = value.id; }, setSearchName: function(value) { this.search_name = value.name; }, clickCallback: function (page_num) { //pagenateで追加 this.current_page = Number(page_num); }, }, mixins: [Util] } </script>

■OrderSearch.vue 検索部分のvueコンポーネント

<template> <div class="mb-2"> <form method="post" onsubmit="return false;"> <div class="form-group row mt-4"> <div class="col-md-3"> <label class="col-form-label text-sm">▼注文番号{{ search_order_id }}</label> <div class=""> <input type="text" class="form-control text-sm form-control-sm" maxlength="30" v-model="search_order_id" @input="$emit('set_order_id', {id:search_order_id})"> </div> </div> <div class="col-md-3"> <label class="col-form-label text-sm">▼名前{{ search_name }}</label> <div class=""> <select class="form-control text-sm form-control-sm" v-model="search_name" @change="$emit('set_name', {name:search_name})"> <option class="text-sm" value="">-----</option> <option v-for="(name, index) in names" v-bind:value="name.value" :key="index"> {{ name.label }} </option> </select> </div> </div> </div> <button class="btn btn-outline-info btn-flat" @click="$emit('aaa', {id:search_order_id, name:search_name})" >検索</button> </form> </div> </template> <script> export default{ props: { }, data() { return { search_order_id: "", search_name: "", names: [ {label: "管理者", value: "管理者"}, {label: "一般", value: "一般"}, ] } }, } </script>

■Controller部分 OrderController function searchのみ抜粋

public function search(Request $request) { $search_order_id = $request->search_order_id; $search_name = $request->search_name; $query = Order::query(); if(!empty($search_order_id)) { $query->where('order_id', 'like', '%'.$search_order_id.'%'); } /* if(!empty($search_name)) { $query->where('name', $search_name); } */ //$orders = $query->paginate(15); //★これだと成功。エラーにならない $orders = $query->get(); //エラーになる //dd($orders); return response()->json($orders); }

Controllerで$ordersを求める部分を、

$orders = $query->paginate(15);

にするとエラーになりませんでした。
しかし、どちらもdd($orders);で検索結果を出力すると、1件と正しく取得されていました。

なぜ$orders = $query->get(); だとエラーになるのか、それとも別のところに原因があるのか、ページネーションはVueで行っているので、コントローラー側でpaginateをやりたくないのですが、いい方法などありましたらご教示いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

FKM

2021/11/19 00:17 編集

$orders = $query->get(); これによるエラーとはVueの方でしょうか?そうだとすると、 var_dump($orders)で出力された値を、pagenate(15)と見比べてみてください。
mikeko0901

2021/11/24 14:23

ありがとうございます。 $orders = $query->get();と$orders = $query->paginate(15);で、var_dump($orders)で出力し比べてみました。取れたデータの数自体は同じでしたが、データが入っている階層が違うなと気づきました。 Vueコンポーネントの方で、 $orders = $query->paginate(15); では、this.orders = response.data.data;のようにして取得していましたが、 $orders = $query->get(); では、this.orders = response.data; で取得しなければいけなかったようです。 response.data.dataだとundefinedとなってしまって、lengthできませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問