Andrei Maieras
Andrei Maieras

Reputation: 706

Vue - passing apollo query result from parent to child component

I have this parent component which makes a call to this apollo query:

<template>
        <div class="row" style="flex-wrap: nowrap; width:102%">
            <BusinessContextTeamPanel :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDetailPanel>
        </div>
</template>
    <script>
        apollo: {
                    business_contexts: {
                        query: gql`query ($businessContextId: uuid!) {
                           business_contexts(where: {id: {_eq: $businessContextId }}) {
                               id
                               businessContextTeams {
                                 id
                                 team {
                                   name
                                   id
                                 }
                                 role
                               }
                           }
                         }`,
                        variables: function() {
                            return {
                                businessContextId: this.currentContextId
                            }
                        }
                    }
                },
    </script>

My child component( BusinessContextTeamPanel) takes the input props and uses it like this:

<template>
    <div v-if="business_contexts.length > 0">
        <div v-for="teams in business_contexts" :key="teams.id">
                        <div v-for="team in teams.businessContextTeams" :key="team.id" style="padding-top: 20px;min-width: 400px">
                            <div style="height: 25px; color: #83d6c0;">

                                <div style="width: 7%; font-size: 10px; float: left; padding-top: 8px; cursor: pointer;" class="fa fa-minus-circle" ></div>

                                <div style="width: 50%; float: left; padding-right: 10px;">
                                    <div class="gov-team-text" @click="editTeam(team)">{{ team.team.name }}</div>
                                </div>

                                <div style="width: auto; float: right;">
                                    <b-badge variant="light">{{ team.role }}</b-badge>
                                </div>
                                <div style="width: 45%; margin-left: 4%; float: right;">
                                </div>
                            </div>
                            <div style="clear: both; margin-bottom: 15px;"></div>
                        </div>

                    </div>
    </div>
</template>

The v-if here throws

Cannot read property 'length' of undefined

while the v-for works. And when I'm trying to use the props in a child method(loadData()) which is called on child component mount hook, I get also undefined

<script>
    import Treeselect from '@riophae/vue-treeselect';
    import _ from "lodash";


    export default {
        name: "BusinessContextTeamPanel",
        components: { Treeselect },
        props: ['business_contexts'],
        data() {
            return {
                itemModel: {},
                allRoles: [],
                formTitle: "",
                filteredTeams: [],
                showNoTeamMsg: false
            }
        },
        mounted() {
            this.loadData();
        },
        methods: {
            loadData() {
                let roles = [];
                _.forEach(["Admin", "Contributor", "Owner", "Master", "Viewer", "User"], function (role) {
                    roles.push({id: role, label: role});
                });
                console.log(this.business_contexts); // here I get undefined
                this.allRoles = roles;
                this.showNoTeamMsg = this.business_contexts.length === 0;
            }
        }
    }
</script>

What am I missing?

Upvotes: 1

Views: 779

Answers (1)

jameslol
jameslol

Reputation: 1935

Either your apollo query isn't working, or it isn't ready in time for the child component's attempted use of it.

For debugging, in the parent component's template add {{ business_contexts }}, just so you can eyeball it. This will confirm whether the query is working.

If the query is working, it could be that your child component is trying to access the data before it's ready. Change your v-if from

<div v-if="business_contexts.length > 0">

to

<div v-if="business_contexts && business_contexts.length > 0">

EDIT: better yet, change the parent component to not try to load the child at all, until the parent has the data:

<BusinessContextTeamPanel v-if="business_contexts" :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDetailPanel>

Upvotes: 1

Related Questions