简体   繁体   中英

Error in nextTick: "RangeError: Maximum call stack size exceeded" in ViewTree

I have a problem when selecting children of tree view, her's the code of my treeview:

<v-treeview
     v-model="selection"
     :items="questionnaires"
     :selection-type="selectionType"
     selectable
     return-object
     open-all
 ></v-treeview>

to fill items and their children I use computed function:

computed: {
        questionnaires () {
            const children = this.modules.map(module => ({
                id: module.id,
                name: module.MODULE_NOM,
                children: this.getChildren(module.id), <-- the problem 
            }))
            return [{
                id: this.formData.id,
                name: this.formData.QSTAIRE_NOM,
                children,
            },]
        },
    },

And to fill the children of children of questionnaire I have the error stack exceed:

getChildren(moduleId){
            axios
                .get(`/questionsDemo/${moduleId}`)
                .then(res => {
                    this.questions = res.data.data || [];
                })
                .catch(function(err) {
                    console.log("erreur lors du chargement des questions", err);
                });
            const questions = []
            console.log("les questions",this.questions);
            for (const question of this.questions) {
                console.log(question);
                questions.push({
                    ...question,
                    name: question.QUEST_TEXT,
                })
            }

            return questions.sort((a,b) => {
                return a.name > b.name ? 1 : -1
            })
        },       
    }

so when I try to select the last children (question) I have this problem:

[Vue warn]: Error in nextTick: "RangeError: Maximum call stack size exceeded"

found in

---> <VTreeviewNode>... (2 recursive calls)
       <VTreeview>
         <VCard>
           <VApp>
             <VContent>
               <VApp>
                 <Layout> at resources/js/components/Layout.vue
                   <Anonymous>
                     <VApp>
                       <App> at resources/js/App.vue
                         <Root>
warn @ app.js:77250
logError @ app.js:78509
globalHandleError @ app.js:78504
handleError @ app.js:78464
(anonymous) @ app.js:78607
flushCallbacks @ app.js:78531
Promise.then (async)
timerFunc @ app.js:78558
nextTick @ app.js:78615
Vue.$nextTick @ app.js:80140
(anonymous) @ app.js:118006
Promise.then (async)
click @ app.js:118004
invokeWithErrorHandling @ app.js:78479
invoker @ app.js:78804
original._wrapper @ app.js:84163
app.js:78513 RangeError: Maximum call stack size exceeded
    at Object.reactiveGetter [as nodes] (app.js:77655)
    at VueComponent.proxyGetter [as nodes] (app.js:81243)
    at VueComponent.getDescendants (app.js:117573)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
    at VueComponent.getDescendants (app.js:117577)
logError @ app.js:78513
globalHandleError @ app.js:78504
handleError @ app.js:78464
(anonymous) @ app.js:78607
flushCallbacks @ app.js:78531
Promise.then (async)
timerFunc @ app.js:78558
nextTick @ app.js:78615
Vue.$nextTick @ app.js:80140
(anonymous) @ app.js:118006
Promise.then (async)
click @ app.js:118004
invokeWithErrorHandling @ app.js:78479
invoker @ app.js:78804
original._wrapper @ app.js:84163
app.0a5fabc74150bf603a11.hot-update.js:282 les questions [{…}, __ob__: Observer]

I see some problems.

a) You are calling an async method (an axios call) inside a computed property:

children: this.getChildren(module.id), <-- here

ans as vue guide states you should use a watcher :

In this case, using the watch option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property.

or you can give a try to the vue-computed-async package .

b) In you method that does the axios call you are not waiting for the results, the method returns before the promise get solved / rejected:

      getChildren(moduleId){
                axios
                    .get(`/questionsDemo/${moduleId}`)
                    .then(res => {
                        this.questions = res.data.data || [];
                    })
                    .catch(function(err) {
                        console.log("erreur lors du chargement des questions", err);
                    });
     
                <!-- FROM HERE YOU ARE NOT WAITING FOR THE THEN BLOCK -->
                const questions = []
                console.log("les questions",this.questions);
                for (const question of this.questions) {
                    console.log(question);
                ....

you can change it to a await or to put the rest of the logic inside the then() block

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM