1

I am getting value as undefined when I try to access this.perMonth from fnTwo() and fnThree() but works in fnOne(). I can run a function from data(){} and can return some values but cannot return that's in data(){} eg.this.perMonth (check fnThree())

Vue.component('BuySubscription', {
  template: '#buy-subscription',
  data() {
    return {
      perMonth: 19,
      valFromFnTwo: this.fnTwo(),
      valFromFnThree: this.fnThree()
    }
  },
  methods: {
    fnOne() {
      console.log("from fnOne: get data > perMonth: " + this.perMonth);
      return this.perMonth
    },
    fnTwo() {
      console.log("from fnTwo: get data > perMonth : " + this.perMonth);
      return this.perMonth
    },
    fnThree() {
      console.log("from fnThree: get data > perMonth " + this.perMonth);
      console.log("from fnThree: get data > valFromFnTwo: " + this.valFromFnTwo);
      return 123 // retruns static value
    }
  }
});

new Vue({
  el: '#app',
});
body { font-family: arial; font-size: 12px}
p {margin: 0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>

<div id="app" class="col-lg-6 d-flex align-items-center">
  <buy-subscription></buy-subscription>
</div>

<script type="text/x-template" id="buy-subscription">
  <div>
    <p>value from data > perMonth: {{perMonth}}</p>
    <p>value from data > valFromFnTwo:  {{valFromFnTwo}} <span style="color: red"> <-- getting Undefined here (see console)</span></p>
    <p>value from fnOne(): {{fnOne()}}</p>
    <p>value from fnTwo(): {{fnTwo()}}</p>
    <p>value from fnThree(): {{fnThree()}}</p>
  </div>
</script>

Also, please consider if I have nested array of data which I like to process:

  data() {
    return {
      perMonth: 19,
      someVarViaFns: [
        {
          valFromFnTwo: this.fnTwo(1),
          valFromFnThree: this.fnThree(2) 
        },        
        {
          valFromFnTwo: this.fnTwo(5),
          valFromFnThree: this.fnThree(9) 
        },
      ]
    }
  }
1

2 Answers 2

6

Calling the Vue instance's methods from within the data method is problematic because the data properties have not been set yet. So, any references to data properties in those methods (this.perMonth in your case) will return undefined .

Set the values of valFromFnTwo and valFromFnThree in the created or mounted hook instead. These hooks fire after the data method has returned, so references to data properties will work as expected.

data() {
  return {
    perMonth: 19,
    valFromFnTwo: null,
    valFromFnThree: null
  }
},
mounted() {
  this.valFromFnTwo = this.fnTwo();
  this.valFromFnThree = this.fnThree();
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for your help. What you defined above seem to be good solution for now, but what if there is nested array of data?
You can just set that in the mounted hook as well. this.someVarViaFns = [{ valFromFnTwo: this.fnTwo(1), ... }, { ... }]
0

I think you're having this issue because of the Hoisting behavior of the JS Engine.

Instead of declaring it in your data use computed properties:

computed: {
  fnTwo() {
    // you can do other operations here also
    // the currency variables is just an example. not mandatory
    let currency = 'usd';

    return "value from fnTwo: " + this.perMonth + ' ' + currency;
  }
}

Then you can render it in your template <p>{{ fnTwo }}</p> or even <p>{{ fnTwo()</p> both should work.

1 Comment

This would make the property reactive to changes of this.perMonth, which might not be what OP wants.

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.