1

I want to pass an array called hours from a Laravel controller to a Vue.js component but for some reason it's not working. As you can see in the following code, I am trying to create dynamically the options inside a select that is located inside a component but for some reasons I see no options in that array. In the view I created a <p> to check that the returning array from controller be correct and finally it is correct because in the view I am able to see the second value of the array. But for some reasons I cannot visualize the values of the array inside the component.

This is my controller code:

    $open_at = '00:00';
    $close_at = '23:45';

    $time = new DateTime($open_at);
    $close = new DateTime($close_at);
    while ($time < $close) {
        $hours[] = $time->format('H:i');
        $time->modify('+15 minutes');
    }

    return view('create')->with('hours', $hours);

This is my view code:

@extends('layouts.app')

@section('content')
<div class="container">
    <div id="app">
        <create-form :hours="hours"></create-form>
    </div>
    <p>
        {{ $hours[1] }}
    </p>
</div>
@endsection

This is code inside the template component:

        <div class="form-group">
            <label for="start">Start Hour:</label>
            <select class="form-control" id="start">
                <option v-for="hour in hours" :key="hour.id">
                    {{ hour }}
                </option>
            </select>
        </div>

This is the my export_default:

export default {
    props: ['hours[]'],
    mounted() {
        console.log('Component mounted.');
        this.loadUsers();
        this.loadRooms();
    },
    data: function() {
        return {
            users: [],
            rooms: []
        }
    },
    methods: {
        loadUsers: function() {
            axios.get('api/users')
            .then((response) => {
                this.users = response.data.data;
            })
            .catch(function(error) {
                alert('noviva');
                console.log(error);
            });
        },
        loadRooms: function() {
            axios.get('api/rooms')
            .then((response) => {
                this.rooms = response.data.data;
            })
            .catch(function(error) {
                alert('noviva');
                console.log(error);
            });
        }
    }
}

I visualize the following warning in the console:

Property or method "hours" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Can help?

1 Answer 1

1

The definition of your props property doesn't match the name by which $hours is passed to the component

props: ['hours'],

And again you do not have id on hours the way you are constructing the hours[] in controller so the template will give another error when you try :key="hour.id

You must either construct the hours array in controller such that it has an id for every entry or (not recommended) you can use the index in the v-for loop as key

<div class="form-group">
    <label for="start">Start Hour:</label>
    <select class="form-control" id="start">
        <option v-for="(hour, index) in hours" :key="index">
            {{ hour }}
        </option>
    </select>
</div>

PHP arrays and objects can be passed to javascript/vue as props by json encoding them

    //Using the blade helper @json
    <div id="app">
        <create-form :hours='@json($hours)'></create-form>
    </div>

   //OR using json_encode()

    <div id="app">
        <create-form :hours="{{ json_encode($hours) }}"></create-form>
    </div>
2
  • donkarnash using you snippet and adding a json_encode() it works. By the way, why are you suggesting me not using your snippet? Commented Dec 21, 2020 at 13:51
  • 1
    No it's not that I'm suggesting you to not use the snippet. Vue docs mention that it's not recommended to use loop index as :key in v-for loops, because when there are multiple components using loop index as key on the same page there can be some side effects/unpredicted behaviour. So if possible always use a unique property on the object being iterated as :key. That said using loop index is not uncommon.
    – Donkarnash
    Commented Dec 21, 2020 at 13:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.