6

I am trying to set my components variable using an api rest command. I wanted to handle all responses through a function in its own file called handleResponse() which is below.

// api/tools/index.js
function handleResponse (promise, cb, cbError) {
  var cbErrorRun = (cbError && typeof cb === "function") 

  promise.then(function (response) {
    if (!response.error) {
      cb(response)
    }
    else if (cbErrorRun) {
      cbError(response)
    }
  }).catch(function (error) {
    console.log(error)
    if (cbErrorRun) {
      var responseError = {
        "status": 404,
        "error": true,
        "message": error.toString()
      }
      cbError(responseError)
    }
  })
}
export {handleResponse}

In my component file I have this

.... More above....
<script>
import { fetchStock } from '@/api/stock'    

  export default {

    data () {
      return {
        stock: {},
        tabs: [
          {
            title: 'Info',
            id: 'info'
          },
          {
            title: 'Listings',
            id: 'listings'
          },
          {
            title: 'Company',
            id: 'company'
          }
        ],
      }
    },
    validate ({params}) {
      return /^\d+$/.test(params.id)
    },
    created: function() {
      var params = {'id': this.$route.params.stockId}
      //this.$route.params.stockId}
      fetchStock(
        params,
        function(response) { //on successful data retrieval
          this.stock = response.data.payload // payload = {'name': test123}
          console.log(response)
        },
        function(responseError) { //on error
          console.log(responseError)
        }
      )
    }
  }
</script>

The current code gives me this error: "Uncaught (in promise) TypeError: Cannot set property 'stock' of undefinedAc". I think this happens because I no longer have access to 'this' within the callback I pass in the fetchStock function. How would I fix this without changing the current handleResponse layout.

2 Answers 2

11

You can try this trick

  created: function() {
      var params = {'id': this.$route.params.stockId}
      //this.$route.params.stockId}
      var self = this;
      fetchStock(
        params,
        function(response) { //on successful data retrieval
          self.stock = response.data.payload // payload = {'name': test123}
          console.log(response)
        },
        function(responseError) { //on error
          console.log(responseError)
        }
      )
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Wow thanks, I have been trying everything and tearing my hair.
2

You can either use an arrow function for you callback since arrow functions maintain and use the this of their containing scope:

created: function() {
      var params = {'id': this.$route.params.stockId}
      //this.$route.params.stockId}

      fetchStock(
        params,
        (response) => { //on successful data retrieval
          self.stock = response.data.payload // payload = {'name': test123}
          console.log(response)
        },
        (responseError) => { //on error
          console.log(responseError)
        }
      )
    }

Or you can assign const vm = this n the beginning of your method before the callbacks like so.

vm stands for "View Model"

  created: function() {
      var params = {'id': this.$route.params.stockId}
      //this.$route.params.stockId}
      const vm = this;
      fetchStock(
        params,
        function(response) { //on successful data retrieval
          self.stock = response.data.payload // payload = {'name': test123}
          console.log(response)
        },
        function(responseError) { //on error
          console.log(responseError)
        }
      )
    }

I advise using the const as opposed to var in the vm declaration to make it obvious the value of vm is a constant.

Comments

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.