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>
Sign up to request clarification or add additional context in comments.

2 Comments

donkarnash using you snippet and adding a json_encode() it works. By the way, why are you suggesting me not using your snippet?
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.