2
votes

I am using a client created with Vue Cli which fetches the data in the API made with Laravel 5.

I tried to load child items on a Treeview Vuetify, but it is not working as expected.

Vuetify Treeview

<v-treeview
    v-model="selected"
    :active.sync="active"
    :open.sync="open"
    :items="items"
    :load-children="getChilds"
    open-on-click
/>

Computed "items".

computed: {          
    items() {
        const leafs = [];
        this.items.forEach(item => leafs.push({id: item.id, name: item.name, children:[]}))
        return leafs
    },          
},

Method that returns the children.

getChilds(item) {              
    return new Promise((resolve, reject) => {
        axios.get("/callgetchilds/" + item.id)
            .then(response => {
                item.children.push(...response.data)
                resolve(response)
            })
            .catch(error => {                
                reject(error)
            });
        })
},

But I get the error below:

TypeError: Cannot set property 'vnode' of undefined
    at a.register (VTreeview.js:257)
    at a.created (VTreeviewNode.js:132)
    at nt (vue.runtime.esm.js:1854)
    at Fn (vue.runtime.esm.js:4213)
    at a.e._init (vue.runtime.esm.js:5002)
    at new a (vue.runtime.esm.js:5148)
    at rn (vue.runtime.esm.js:3283)
    at init (vue.runtime.esm.js:3114)
    at p (vue.runtime.esm.js:5972)
    at m (vue.runtime.esm.js:5919)

Someone who has been through this could help me or show me what I am doing wrong.

Thank you

Edited and added after further testing to try to help with more information about the issue.

I will try to explain something that I realized, I hope I can make myself understood.

I have as tables the following structure to use in this treeview:

Table "Parent"
    -id
    -name

Table "Child"
    -id
    -parent_id    
    -Other attributes below...
    ...

When loading the trereview, initially I have Json that returns the data from the "Parent" table.

Clicking on any item on Treeview, she queries and fetches the children in the "Child" table.

Imagine the Parent nodes being as follows:

LEAFS (2 Parent Nodes)
    id: 1
        name: "LEAF 1"
        children: Array(0)
    id: 2
        name: "LEAF 2"
        children: Array(0)

When I try to load the children from LEAF 1, it returns.

children: 
    0:                
        id: 4            
        name: "Any child name here"
        parent_id: 1
    1:                
        id: 5
        name: "Any child name here"
        parent_id: 1

The error occurs on component/line: VTreeview.js: 257

There we have the following method:

255: register(node) {
256:    const key = getObjectValueByPath(node.item, this.itemKey);
257:    this.nodes[key].vnode = node;
258:    this.updateVnodeState(key);
259: },

The treeview is returning the child ID as key and trying to find a node at this position in the parent.

But notice that I have only 2 Parent nodes (Leafs), position 4 or 5 obviously do not exist.

This could be a bug in the component.

2
You should rename your computed property, it should not have the save name as a data property. Also in your {id: item.id, item.name: name, children:[]} it should be name: item.name. - Brandon Pratt
Thanks so much for answering, but that had just been a typo. I just fixed the post, the problem persisted. - hsdev
Did you rename the computed property? - Brandon Pratt
I just tried it, but had the same error. - hsdev
Just to verify, you also updated :items="items" to use the new name? - Brandon Pratt

2 Answers

2
votes

I just had the same problem and made a quick workaround where I clone the parent node.

Before pushing the children items

item.children.push(...response.data)

Try this:

const key = item.id
const parentNode = this.$refs.treeReference.nodes[key]

let childNode;
children.forEach((child) => {
  childNode = {...parentNode, item: child, vnode: null}
  this.$refs.treeReference.nodes[child.id] = childNode
})

where treeReference is a ref to your TreeView.

Not the best solution but this fixed it for me.

2
votes

I had the same issue and could not resolve it. I did find a work around.

This is only for: vuetify 1.5.x, and it might not work with: vuetify 2.0.0 +.

Add return-object to your treeview component, drop the :load-children="getChilds" and rather use

<v-treeview
    v-model="selected"
    :active.sync="active"
    :open.sync="open"
    :items="items"
    return-object
    open-on-click
>
    <template v-slot:label="{item, active}">
       <div @click="getChilds(item)">{{item.name}}</div>
    </template>
</v-treeview>

In your methods:

getChilds(item) { 
    let self = this;             
    axios.get(`/callgetchilds/${item.id}`)
    .then(response => {
        item.children.push(...response.data)
        self.open = item;

     }).catch(error => {                
         //handle error 
     });
},

This allows you more freedom to do things too...