LoginSignup
2024_Hello_World
@2024_Hello_World

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

JSONデータをVueコンポーネントで取得して変数に入れる方法。

解決したいこと

データ分析画面で分析するデータの期間をフォームから選択して分析ボタン押すと
指定した期間内のデータをJSON形式で取得して変数にセットしたのちにコンソールに出力したい。

画面レイアウト

スクリーンショット 2024-06-07 181430.png

開発環境

フロントエンド 
vue.js 3.2
Inertia.js 1.0

バックエンド
Laravel 9.52.16

データをJSON形式でVue側へ渡せたのですが、変数へセットする方法が分かりません。
Analysis.vueのonMountedの中でconsole.logを試したところ実行されなかった。

発生している問題・エラー

All Inertia requests must receive a valid Inertia response, however a plain JSON response was received.

【ブラウザに表示されているメッセージ】
スクリーンショット 2024-06-09 063844.png

【コンソール上】ログには出力してくれなかった
スクリーンショット 2024-06-09 063914.png

該当するソースコード

Analysis.vue
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head } from '@inertiajs/vue3';
import { onMounted } from 'vue';
import { getToday } from '@/common';
import { useForm } from '@inertiajs/vue3'

const props = defineProps({
    data: Object
})

onMounted(() => {
    form.startDate = getToday()
    form.endDate = getToday();
    console.log(props);
})

const form = useForm({
    startDate: null,
    endDate: null,
    type: 'perDay'
})

</script>

<template>
    <Head title="データ分析" />

    <AuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">データ分析</h2>
        </template>

        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 text-gray-900">
                        <form @submit.prevent="form.post(route('data.analysis'))">
                            From: <input type="date" name="startDate" v-model="form.startDate">
                            To: <input type="date" name="endDate" v-model="form.endDate"><br>
                            <button class="mt-4 flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">分析する</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </AuthenticatedLayout>
</template>

web.php
<?php
use Illuminate\Support\Facades\Route;

Route::post('data/analysis', [ App\Http\Controllers\Data\AnalysisController::class, 'index'])
->name('data.analysis');
AnalysisController.php
<?php
<?php

namespace App\Http\Controllers\Data;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Models\Order;
use Illuminate\Support\Facades\DB;

class AnalysisController extends Controller
{
    public function index(Request $request)
    {
        //orderモデルから期間内のデータを取得する
        $subQuery = Order::betweenDate($request->startDate, $request->endDate);

        if ($request->type === 'perDay')
        {
            $subQuery->where('status',true)
            ->groupBy('id')
            ->selectRaw('SUM(subtotal) AS totalPerPurchase, DATE_FORMAT(created_at, "%Y%m%d") AS date')
            ->groupBy('date');

            $data = DB::table($subQuery)
            ->groupBy('date')
            ->selectRaw('date, sum(totalPerPurchase) as total')
            ->get();
        }
        return response()->json([
            'data' => $data,
            'type' => $request->type
        ], Response::HTTP_OK);
    }
}

自分で試したこと

・ChatGptで調べてみた。
Inertiaリクエストに対してはInertiaレスポンスとしてJSONを返す必要があるみたいだったので
Inertia::renderを使ったコードに書き換えましたが別のエラーが発生しました。

AnalysisContoroller.php
<?php

namespace App\Http\Controllers\Data;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Models\Order;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class AnalysisController extends Controller
{
    public function index(Request $request)
    {
        //orderモデルから期間内のデータを取得する
        $subQuery = Order::betweenDate($request->startDate, $request->endDate);

        if ($request->type === 'perDay')
        {
            $subQuery->where('status',true)
            ->groupBy('id')
            ->selectRaw('SUM(subtotal) AS totalPerPurchase, DATE_FORMAT(created_at, "%Y%m%d") AS date')
            ->groupBy('date');

            $data = DB::table($subQuery)
            ->groupBy('date')
            ->selectRaw('date, sum(totalPerPurchase) as total')
            ->get();
        }
        
                if ($request->header('X-Inertia')) {
                    //dd関数で$requestが取得できていることは確認できた。
                    // dd($request);
                    return Inertia::render('Analysis', [
                        'data' => $data,
                        'type' => $request->type
                    ], Response::HTTP_OK);
                }
    }
}

新たに発生しているエラー

@inertiajs_vue3.js?v=c8f87184:2901 Uncaught (in promise) TypeError: this.resolveComponent is not a function

スクリーンショット 2024-06-09 064452.png

1

1Answer

vueの経験しかないですが所見を述べますと、
ボタンクリック時の動作がform.post(route('data.analysis'))だけかと思います。
これはデータをリクエストしているだけかと思いますので、リクエストした後に取得できたデータをconsole.log()で出力するコードを追加しないといけないかと思います。

以下などで試してみて頂けますか?

Analysis.vue
<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head } from '@inertiajs/vue3';
import { onMounted } from 'vue';
import { getToday } from '@/common';
import { useForm } from '@inertiajs/vue3'

const props = defineProps({
    data: Object
})

onMounted(() => {
    form.startDate = getToday()
    form.endDate = getToday();
    console.log(props);
})

const form = useForm({
    startDate: null,
    endDate: null,
    type: 'perDay'
})

</script>

<template>
    <Head title="データ分析" />

    <AuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">データ分析</h2>
        </template>

        <div class="py-12">
            <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-6 text-gray-900">
+                       <form @submit.prevent="form.post(route('data.analysis'), { onSuccess: (res) => console.log(res) })">
                            From: <input type="date" name="startDate" v-model="form.startDate">
                            To: <input type="date" name="endDate" v-model="form.endDate"><br>
                            <button class="mt-4 flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">分析する</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </AuthenticatedLayout>
</template>
0

Your answer might help someone💌