2

I'm working with 3 VUE nested components (main, parent and child) and I'm getting trouble passing data.

The main component useget a simple API data based on input request: the result is used to get other info in other component.

For example first API return the regione "DE", the first component is populated then try to get the "recipes" from region "DE" but something goes wrong: The debug comments in console are in bad order and the variable used results empty in the second request (step3):

  app.js:2878 Step_1: DE 
  app.js:3114 Step_3:  0
  app.js:2890 Step_2: DE

This is the parent (included in main component) code:

parent template:

<template>
   <div>
       <recipes :region="region"/>
   </div>
</template>

parent code:

 data: function () {
        return {
            region: null,
        }
    },

 beforeRouteEnter(to, from, next) {

        getData(to.params.e_title, (err, data) => {
           
             console.log("Step_1: "+data.region); // return  Step_1: DE

             // here I ned to update the region value to "DE"
           
            next(vm => vm.setRegionData(err, data));
        });
    },

    methods: {
        setRegionData(err, data) {
            if (err) {
                this.error = err.toString();
            } else {
                console.log("Step_2: " + data.region); // return DE
                this.region = data.region;
                
            }
        }
    },

child template:

<template>
     <div v-if="recipes" class="content">
      <div class="row">
            <recipe-comp v-for="(recipe, index) in recipes" :key="index" :title="recipe.title" :vote="recipe.votes">
    </recipe-comp>
        </div>
       </div>
     </template>

child code:

props: ['region'],
....
 beforeMount () {
        console.log("Step_3 "+this.region); // Return null!!
        this.fetchData()
    },

The issue should be into parent beforeRouteEnter hook I think.

Important debug notes:

1) It looks like the child code works properly because if I replace the default value in parent data to 'IT' instead of null the child component returns the correct recipes from second API request. This confirms the default data is updated too late and not when it got results from first API request.

data: function () {
    return {
        region: 'IT',
    }
},

2) If I use {{region}} in child template it shows the correct (and updated) data: 'DE'!

I need fresh eyes to fix it. Can you help me?

5
  • 1
    Instead of beforeMount in the child, you may be able to use a watch for that prop..? When that prop changes, it fires the this.fetchData? I would honestly need to see more of the code to get a full grasp of the logic... this feels like a logistical issue. Commented May 18, 2019 at 18:30
  • Yes I think it's a logic issue too. I have updated the question with more details: basically the first step get the ID from user input and run the first API request which return the user data (REGION) . The second component should pass the REGION to second API request to get the recipes but... something is wrong (See the first code console log block in my post). AThe value passed is not updated yet. Commented May 19, 2019 at 5:20
  • Yes! Thanks! watch 'region': 'fetchData' works perfectly! I was so close, I tested 'this.region' but I had to use just 'region'. Thanks again for your time! Commented May 19, 2019 at 5:51
  • 1
    Totally!!! Thanks again Matt for your kind help! I'm a beginner on Vue.js and I was getting crazy using bad watch use. When you post your answer I'll submit it and I'll delete my answer to myself. thanks. Commented May 19, 2019 at 6:01
  • <3 thank you, @Uncoke Commented May 19, 2019 at 6:10

1 Answer 1

2

Instead of using the beforeMount hook inside of the child component, you should be able to accomplish this using the watch property. I believe this is happening because the beforeMount hook is fired before the parent is able to set that property.



In short, you can try changing this:

props: ['region'],
....
 beforeMount () {
    console.log("Step_3 "+this.region); // Return null!!
    this.fetchData()
},

To something like this:

props: ['region'],
....
 watch: {
    region() {
        console.log("Step_3 "+this.region); // Return null!!
        this.fetchData()
    }
},

Cheers!!

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect thanks! It works.As you suggested I used the shortcut for watch: watch: { 'region': 'fetchData'}, and now component and sub components are sync! Yeah!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.