Understanding Props Passed to router-view for Vue Child Component, Prop Data Not Rendering

197 views Asked by At

I know this has been asked in several other posts on StackOverflow, though I'm still running into a wall with trying to solve my issue. I'm very much new to Vue and trying to learn this stack but having some struggles with this aspect

PROBLEM: In following along with a tutorial I have a page called "Menu Editor" that uses Vue Router to automatically redirect the user to a child component called "Category Manager" within the Menu Editor page. However, when on the "Menu Editor" page the prop data will not show regardless of what I've attempted thus far (reading and trying solutions proposed in similar posts such as this) from my menu editor vue file, i know the issue lies with <router-view v-bind:inital-categories="categories"></router-view>

from my app.js file I have my two components registered as such

   Vue.component('category-manager', require('./components/category-manager.vue').default);
   Vue.component('menu-editor', require('./components/menu-editor.vue').default);

my menu-editor.vue file

<template>
    <div>
        <h1>Menu Editor</h1>
        <router-link :to="{name: 'categories'}">Categories</router-link>
        <router-link :to="{name: 'add-item'}">Add Item</router-link>

        <router-view v-bind:inital-categories="categories"></router-view>
    </div>
</template>

<script>
    import VueRouter from 'vue-router';
    import CategoryManager from './category-manager.vue';
    import MenuItem from './menu-item.vue';

    export default {
        props:['categories'],
        router: new VueRouter({
            mode: 'history',
            routes: [
                {
                    path: '/categories',
                    name: 'categories',
                    component: CategoryManager
                },
                {
                    path: '/menu-editor',
                    redirect: {name: 'categories'}
                },
                {
                    path: '/add-item',
                    name: 'add-item',
                    component: MenuItem
                }
            ]
        })
    }
</script>

<style scoped>
    a{
        border: solid 1px black;
        padding: 10px;
        margin: 0;
    }

    .router-link-active{
        font-weight: bold;
        border-bottom: none;
    }
</style>

my category-manager.vue file

<template>
    <form  @submit.prevent="saveCategories">
        <a @click="addCategory(index)" class="add">+ add category</a>

        <div v-for="(category,index) of categories" :key="category.id">
            <input type="text" v-model="category.name" :ref="category.name">
            <input type="number" v-model="category.display_order">
            <a @click="removeCategory(index)" class="remove">delete</a>
            <div>
                <img v-if="category.image" :src="`/images/${category.image}`" width="100">
                <label v-else>Image: </label>
                <input type="text" v-model.lazy="category.image">
            </div>
            <hr>
        </div>
        <button type="submit">Save</button>
        <div>{{ feedback }}</div>
    </form>
</template>

<script>
    export default {
        props: ['initialCategories'],
        data(){
            return{
                categories: _.cloneDeep(this.initialCategories),
                feedback: '',
            };
        },
        methods: {
            removeCategory(index){
                if(confirm('are you sure?')){
                    let id = this.categories[index].id;
                    if(id > 0){
                        console.log('calling delete /api/categories/' + id);
                        axios.delete('/api/categories/' + id);
                    }
                    this.categories.splice(index,1);
                }
            },
            addCategory(index){
                this.categories.push({
                    id: 0,
                    name: '',
                    display_order: this.categories.length + 1
                });
                this.$nextTick(() =>{
                    window.scrollTo(0, document.body.scrollHeight);
                    this.$refs[''][0].focus();
                });
            },
            saveCategories(){
                axios.post('/api/categories/upsert', {
                    categories: this.categories
                })
                .then((res) => {
                    if(res.data.success){
                        this.feedback = 'Changes saved.';
                        categories = res.data.categories;
                    }
                });
            }
        }

    }
</script>

<style scoped>
    img {
        vertical-align: middle;
    }
    hr {
        margin-bottom: 30px;
    }
</style>

my menu-editor.blade.php file

@extends('layouts.app')

@section('title', '- Menu Editor')

@section('content')
    <menu-editor :categories="{{ $categories }}"></menu-editor>
@endsection

my AdminController.php file

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Categories;

class AdminController extends Controller
{
    //
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function menu(){
        //
        $categories = Categories::orderBy('display_order')->get();
        return view('admin.menu-editor', [
            'categories' => $categories
        ]);
    }
}

When on the "Menu Editor" the view returns as such menu editor

with the data returned to the DOM as "[object Object],[object Object]" instead of the objects being rendered correctly. inital-categories="[object Object],[object Object]"

However, when I go directly to the "/categories" page without first going to the "Menu Editor", the data shows fine.

This is what the "categories" page looks like when visited directly (without having the two menu buttons at the top of the page as the Menu Editor does) category manager

Can someone please show me where I am going wrong so that I can correctly show the prop data on the Menu-Editor page? Thanks in advance! I'm sure that I'm overlooking something silly but would really appreciate any help in finding and fixing my error.

0

There are 0 answers