0

I am trying to update taxParentId with the new id that i retrieve with my API call inside the getTaxParentId function, but I cannot get it to change. I can console.log the value fine inside the method, but it won't update it. It seems to be an issue of scope, but i have set $this = this to take care of this, however, it is not working.

the getPostType method works fine and properly updates the data value.

var newVue = new Vue({
  el: '#app',
  data() {
    return{
      posts: [],
      taxonomy: '',
      postType: '',
      taxParentSlug: '',
      taxParentId: 0
    }
  },
  created (){
    let $this = this;
    this.getPostType(location.href);
    this.getTaxParent(location.href)
    this.getTaxParentId();
    this.getPosts();

  },
  methods: {
    getPostType: function(currentURL){
        if (currentURL.includes('residential')) {
            this.postType = 'residential';
        }else if(currentURL.includes('commercial')){
            this.postType = 'commercial';
        }else if (currentURL.includes('auto')) {
            this.postType = 'auto';
        }
    },
    getTaxParent: function(currentURL){
        if (currentURL.includes('solar')) {
            this.taxParentSlug = 'solar';
        }else if(currentURL.includes('decorative')){
            this.taxParentSlug = 'decorative';
        }else if (currentURL.includes('safety-security')) {
            this.taxParentSlug = 'safety-security';
        }
    },
    getTaxParentId: function(){
        let $this = this;

        axios
          .get(apiRoot + $this.postType + '-categories')
          .then(function (response) {
            response.data.forEach(function(item){
                if (item.slug == $this.taxParentSlug) {
                    $this.taxParentId = item.id;
                }
            });
          }
        )
    },
    getPosts: function(){
        let $this = this;

        console.log(apiRoot + $this.postType + '-categories?parent=' + $this.taxParentId)
        axios

          .get(apiRoot + $this.postType + '-categories?parent=' + $this.taxParentId)
          .then(function (response) {
            $this.posts = response.data;
            console.log($this.posts)
          }
        )
    },
  },

});
11
  • I don't see anything wrong with your code. Have you shared it exactly as it is written in your application? Commented Aug 29, 2018 at 20:44
  • yep. Copied and pasted. That's why i am baffled Commented Aug 29, 2018 at 20:45
  • What is the value of currentURL when you console log it? Commented Aug 29, 2018 at 20:49
  • 1
    I would share your whole component code, as the issue is almost certainly something that you don't think is relevant. Commented Aug 29, 2018 at 20:52
  • 1
    Ok, so your getTaxParentId makes an async call, so the then callback won't have executed when the getPosts gets called. You should return the axios call in your getTaxParentId function: return axios.get(...). This will return the Promise and so then you can add a then handler for the getTaxParentId itself and then put the getPosts call within the callback: this.getTaxParentId().then(() => this.getPosts()) Commented Aug 29, 2018 at 21:05

2 Answers 2

1

Because of the async, add watchers to your data, and log there.

watch:{
    posts(value){console.log(value))},
    taxParentId(value){console.log(value))}
}

Ideally you would get a promise from each call, and then wait for them all. If one call is dependent on another, you need to put the second call in a then() block, or even better, await it (async/await)

Using this, all you need to do is return the promise, and it will be synchronized.

  async created (){
    let $this = this;
    await this.getPostType(location.href);
    await this.getTaxParent(location.href)
    await this.getTaxParentId();
    await this.getPosts();
  },

So much cleaner then chaining then blocks. You can wrap the entire block in a SINGLE catch, and trap all exceptions AND all rejections. Of course, if the calls are not dependent, you may want to call them in parallel and not await.

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

4 Comments

When I do that, I get the proper value for taxParentId that I am setting in the function, but when i make the API call in getPosts the value is still the default value
Call getPosts() in the return of getTaxParentId(). You are calling it before the other function returns.
i just changed it to that and it worked. No clue why i didnt do that the first time
I will add another suggestion to solution too... I'm a big fan of async/await.
0

Since you are already using promises, you should be able to build a promise chain to solve your async issue.

Take your current function: ```javascript getTaxParentId: function(){ let $this = this;

    axios
      .get(apiRoot + $this.postType + '-categories')
      .then(function (response) {
        response.data.forEach(function(item){
            if (item.slug == $this.taxParentSlug) {
                $this.taxParentId = item.id;
            }
        });
      }
    )
},

and make it return a value, even if it is just the response ```javascript getTaxParentId: function(){ let $this = this;

    axios
      .get(apiRoot + $this.postType + '-categories')
      .then(function (response) {
        response.data.forEach(function(item){
            if (item.slug == $this.taxParentSlug) {
                $this.taxParentId = item.id;
            }
        });
        return response
      }
    )
},

Then in your created() function, you can chain the call..

created (){
    let $this = this;
    this.getPostType(location.href);
    this.getTaxParent(location.href)
    this.getTaxParentId()
     .then(function (response) {
        this.getPosts();
    })
  },

This should force this.getPosts() to wait for getTaxParentId to be complete.

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.