Home > Net >  Vue prop is sent from a component is undefined
Vue prop is sent from a component is undefined

Time:03-02

I have a Kanban board inside my dashboard which displays issues of a project. I added a menu to allow the user to filter the kanban board by project such that only one project's issue are visible at once. The default view is the issues of all the projects.
In my Dashboard component, I get the list of all projects from a server using axios (which works correctly).
When a user chooses a project, I send to the Kanban board component a prop which is the project id so that I can fetch that project's issues from the server.
However, the prop I'm sending from Dashboard is undefined somehow, and I cannot figure out why

Dashboard.vue

<template>
  <v-container>
    <v-row >
      <v-col cols="3">
        <h2 style="font-size:40px;color:rgb(92, 92, 92)">Kanban Board</h2>
      </v-col>
      <v-col cols="7"></v-col>
      <v-col cols="2">
        <v-menu offset-y>
          <template v-slot:activator="{ on, attrs }">
            <v-btn color="primary" dark v-bind="attrs" v-on="on">
              View
            </v-btn>
          </template>
          <v-list>
            <v-list-item v-for="(project, index) in ProjectList" :key="index">
              <v-list-item-title @click="changeView(project.id)">{{ project.title }}</v-list-item-title>
            </v-list-item>
          </v-list>
        </v-menu>
      </v-col>
    </v-row>
    <v-row>
      <KanBanBoard :projectid="project_id"></KanBanBoard>
    </v-row>
  </v-container>
</template>

<script>
import KanBanBoard from './KanBanBoard.vue'
import { mapGetters, mapActions } from 'vuex'

export default {
  components: {
    KanBanBoard,
  },

  data() {
    return {
      project_id: '',
    }
  },

  computed: {
    ...mapGetters(['ProjectList']),
  },

  methods: {
    ...mapActions(['getProjectList']),

    changeView(project_id) {
      this.project_id = project_id
      
    },
  },

  created() {
    this.getProjectList()
  },
}
</script>

<style scoped>
.view {
  font-size: 20px;
}
</style>

NavBar.js (Vuex file Dashboard uses to get the list of projects)

import axios from 'axios'

const state = {
  Projects: [],
  ProjectsIssuesList: []
}

const getters = {
  ProjectList: (state) => state.Projects,
  ProjectIssuesList: (state) => state.ProjectsIssuesList
}

const actions = {
  async getProjectList({ commit }) {

    var projectList = []
    var issuesList = []
    await axios
        .get('https://fadiserver.herokuapp.com/api/v1/my-projects/')
        .then(response => {
          projectList = response.data

          for (let i = 0; i < projectList.length; i  ) {
            let projectid = projectList[i].id
            
            axios
              .get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid='   projectid)
              .then(response => {
                issuesList.push(response.data)
              })
              .catch(error => {
                console.log(error)
              })
          }
        })
        .catch(error => {
          console.log(error)
        })

    commit('setProjects', projectList),
    commit('setProjectsIssues', issuesList)
  },
}

const mutations = {
  setProjects: (state, Projects) => (state.Projects = Projects),
  setProjectsIssues: (state, ProjectsIssuesList) => (state.ProjectsIssuesList = ProjectsIssuesList)
}

export default {
  state,
  getters,
  actions,
  mutations
}

KanBanBoard.vue

<template>
  <v-container>
    <v-row wrap>
      <v-col xl="4" lg="4" md="4" sm="4" xs="12">
        <v-card>
          <v-card-title >
            <span >Open</span>
          </v-card-title>
          <v-divider horizontal></v-divider>
          <v-card-text >
            <draggable  :list="Open" group="tasks">
              <v-card
                
                style="height:auto; margin-top:10px"
                v-for="issue in Open"
                :key="issue"
                align-center
                elevation="3"
              >
                <v-card-text>
                  <v-row dense style="width:auto">
                    <router-link
                      
                      style="font-size:18px;"
                      :to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
                    >
                      {{ issue.title }}
                    </router-link>
                  </v-row>

                  <v-row dense>
                    <v-col>
                      <v-chip
                        
                        color="red"
                        outlined
                        style="position:relative; right:10px;top:10px; height:min-content"
                      >
                        {{ issue.issueSeverity }}
                      </v-chip>
                    </v-col>
                    <v-col>
                      <v-chip
                        
                        color="green"
                        outlined
                        style="position:relative; right:83px; top:10px;height:min-content"
                      >
                        {{ issue.issueType }}
                      </v-chip>
                    </v-col>
                  </v-row>
                </v-card-text>
              </v-card>
            </draggable>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col xl="4" lg="4" md="4" sm="4" xs="12">
        <v-card>
          <v-card-title >
            <span >In Progress</span>
          </v-card-title>
          <v-divider horizontal></v-divider>
          <v-card-text >
            <draggable  :list="InProgress" group="tasks">
              <v-card
                
                style="height:auto; margin-top:10px"
                v-for="issue in InProgress"
                :key="issue"
                align-center
                elevation="3"
              >
                <v-card-text>
                  <v-row dense style="width:auto">
                    <router-link
                      
                      style="font-size:18px;"
                      :to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
                    >
                      {{ issue.title }}
                    </router-link>
                  </v-row>

                  <v-row>
                    <v-col>
                      <v-chip
                        
                        color="red"
                        outlined
                        style="position:relative; right:10px;top:10px; height:min-content"
                      >
                        {{ issue.issueSeverity }}
                      </v-chip>
                    </v-col>

                    <v-col>
                      <v-chip
                        
                        color="green"
                        outlined
                        style="position:relative; right:83px; top:10px;height:min-content"
                      >
                        {{ issue.issueType }}
                      </v-chip>
                    </v-col>
                  </v-row>
                </v-card-text>
              </v-card>
            </draggable>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col xl="4" lg="4" md="4" sm="4" xs="12">
        <v-card>
          <v-card-title >
            <span >Completed</span>
          </v-card-title>
          <v-divider horizontal></v-divider>
          <v-card-text >
            <draggable  :list="Completed" group="tasks">
              <v-card
                
                style="height:auto; margin-top:10px"
                v-for="issue in Completed"
                :key="issue"
                align-center
                elevation="3"
              >
                <v-card-text>
                  <v-row dense style="width:auto">
                    <router-link
                      
                      style="font-size:18px;"
                      :to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
                    >
                      {{ issue.title }}
                    </router-link>
                  </v-row>

                  <v-row dense>
                    <v-col>
                      <v-chip
                        
                        color="red"
                        outlined
                        style="position:relative; right:10px;top:10px; height:min-content"
                      >
                        {{ issue.issueSeverity }}
                      </v-chip>
                    </v-col>
                    <v-col>
                      <v-chip
                        
                        color="green"
                        outlined
                        style="position:relative; right:83px; top:10px;height:min-content"
                      >
                        {{ issue.issueType }}
                      </v-chip>
                    </v-col>
                  </v-row>
                </v-card-text>
              </v-card>
            </draggable>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import draggable from 'vuedraggable'
import { mapGetters, mapActions } from 'vuex'

export default {
  props: ['project_id'],

  components: {
    draggable,
  },

  computed: {
    ...mapGetters(['Open']),
    ...mapGetters(['InProgress']),
    ...mapGetters(['Completed']),
  },

  watch: {
    projectid() {
      this.fetchIssuesofProject(this.project_id)
      this.test()
    },
  },

  methods: {
    ...mapActions(['fetchIssuesofProject']),
    test() {
      console.log(this.projectid)
    },
  },

  created() {
    this.test(), this.fetchIssuesofProject(this.project_id)
  },
}
</script>

<style scoped>
hr {
  margin-top: 0.1px;
  margin-bottom: 0.1px;
  border: 1;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}
</style>

Kanban.js

import axios from 'axios'

const state = {
    Issues: [],
}

const getters = {
    Open: (state) => state.Issues.filter(x => x.issueStatus == 'Open'),
    InProgress: (state) => state.Issues.filter(x => x.issueStatus == 'In Progress'),
    Completed: (state) => state.Issues.filter(x => x.issueStatus == 'Closed'),
} 

const actions = {
    

    async fetchIssuesofProject({ commit }, projectid) {
        const response = await axios.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid='   projectid).catch(error => {
            console.log("The error is here")
          })
        commit('setIssues', response.data)
    }
}

const mutations = {
    setIssues: (state, Issues) => (state.Issues = Issues)
}

export default {
    state,
    getters,
    actions,
    mutations
}```

CodePudding user response:

Probably it's because in KanBanBoard.vue you defined your prop as project_id and in Dashboard.vue you're passing it like this:

<KanBanBoard :projectid="project_id"></KanBanBoard>

instead do:

<KanBanBoard :project_id="project_id"></KanBanBoard>
  • Related