1
votes

When I try to bind an array as variable and try to access this variable in the child component it says the variable is undefined. Is there a way to pass an array (from a view) to a component (that uses this array to create a child component for each item in the array).

I did manage to create a loop in a component and use this array to create sub components for every item in the array. However, I want to make this component dynamic so it can get an variable array with items from a parent component.

Parent view:

<template>
    <div class="choose-method-container">
        <choose-method-component :availablemethods="availablemethods" v-model="availablemethods" v-bind:title="title" v.bind:items_per_row="items_per_row" />
    </div>
</template>


<script>
    import ChooseMethodComponent from 

    '../components/ChooseMethodComponent.vue';

        export default {
            components: {
                ChooseMethodComponent
            },
            methods: {

            },

            data: function() {
                return {
                    title: 'Choose user type',
                    items_per_row: 2,
                    availablemethods: [
                      {title: 'Data',  description: '', route: '/data'},
                      {title: 'Sales & Support',  description: '', route: '/sales'},      
                    ]
                }
            },
    </script>

child component

<template>
    <div class="choose-method-inner-container">
        <div class="card-container row flexbox" v-for="chunk in productChunks">
            <stepcard-component v-for="step_card in chunk" class="step-card"
                v-bind:key="step_card.value"
                v-bind:title="step_card.title"
                v-bind:description="step_card.description"
                v-bind:name="step_card.name"
                v-bind:value="step_card.value"
                v-bind:view="step_card.view"
                >
            </stepcard-component>
        </div>


        <div class="button-container right">
            <button type="submit" class="btn waves-effect waves-light" :disabled="choose_method_disabled"  v-on:click="choose_method">
                Choose method
            </button>
        </div>
    </div>
</template>


<script>
    import lodash from 'lodash';
    import StepCard from './StepCard.vue';

    export default {
        components: {
            StepCard
        },

        data: function() {
            return {
                choose_method_disabled: true,
            }
        }, 

        mounted() {

              console.log('mounted methods', {availablemethods: this.availablemethods, title:this.title});
            this.productChunks();
        },


            computed: {

            },

            props: {
                availablemethods: Array,
            },

            methods: {
                choose_method: function() {
                    console.log('choose_method', this.method_view);
                    if(!this.method_view)
                        return;

                        this.$router.push({name: this.method_view});
                },

                productChunks() {
                    console.log('methods', this.availablemethods);
                    if(!this.availablemethods){
                        console.log('self', {self:this});
                        return;
                    }
                    var methods = this.availablemethods.forEach(function(method, index){
                        if(!method.name)
                            method.name= '';

                        if(!method.view)
                            method.view= '';

                        if(!method.value)
                            method.value= '';

                        if(!method.description)
                            method.description= '';

                        if(!method.title)
                            method.title= '';

                        return method;
                    });            
                    let chunks = lodash.chunk(methods, this.items_per_row);
                    console.log('productChunks', {chunks:chunks});
                    return chunks;
                }
            }
        }
    </script>

I was hoping to access availablemethods in the child component however it logs undefined. is there any way to pass the array successfully (without declaring and setting the array data in the child).

1
Unless I am miss-understanding your problem, there must be some other issue going on because you can pass an array as a prop exactly the way you have it in your code. See this jsfiddle.net/skribe/nvj2587g/34 Are you using Vue.js devtools in your browser? Can you see any errors.skribe
when I access availablemethods in the template itself (without productChunks) it does indeed work. Why is availablemethods then undefined in the mounted/produceChunks functions, while being known in the template? (same component for both the template and the function)RainyRain
Are you saying that ` console.log('methods', this.availablemethods);` in productChunks() returns undefined? jsfiddle.net/skribe/nvj2587g/41skribe
@skribe it does indeed return undefined. <stepcard-component v-for="step_card in availablemethods" class="step-card" .... > does however work.RainyRain

1 Answers

1
votes

I think your problem is actually with yourvar methods = this.availablemethods.forEach() It is returning methods as undefined.

Try restructuring something like the following (untested)

productChunks() {
      let methods = [];
      this.availablemethods.forEach((method, index) => {
                    if(!method.name)
                        method.name= '';

                    if(!method.view)
                        method.view= '';

                    if(!method.value)
                        method.value= '';

                    if(!method.description)
                        method.description= '';

                    if(!method.title)
                        method.title= '';

                     methods.push(method);

                });

                let chunks = lodash.chunk(methods, this.items_per_row);
                return chunks;
},