skip to Main Content

Good morning,

I have an API written in Django Rest Framework. The front end is written in VueJS. I have a form view that is either an Add New or a Modify. Basically, the form is the same code, but checks to see if the path includes an ID (and thus, is a modify).

To modify the entry, there are a series of API calls for all the various options in dropdown / select menus. These are one-to-one foreign keys on the model (i.e. an actor has a category) and a couple that are many-to-many keys on the model (i.e. actor has one or more motivations).

My big issues right now is that each of these options (there are fourteen total) has an API call. It seems to me that the options are returning and then rendering without all of API calls finished. In the past, I have just used a boolean value for "loading" to do a v-if statement.

With so many, I had a list of boolean values and embedded within the v-if:

<b-container v-if="load_list.every((x) => x)">


data () {
    return {
           load_list: [true, true, true, true, true, true, true, true, true],

Then I tried with a computed value:

<b-container v-if="listLoaded">

computed: {
    listLoaded: function() {
      return this.load_list.every((x) => x)
    }

All of the values get adjusted on the returns of the API calls and the list becomes all false, but the container isn’t changing.

Example API call that is called from the Vue created, which calls a function that makes the call to the DRF endpoint with axios (data returns just fine):

created: function() {
      API.getActor(this.id)
        .then(a => {
          this.getActor(a)
        })
        .catch(error=> console.log(error))
        .finally(() => {
          this.load_list[0] = false
        })

How can I make sure all my of my API return prior to the view rendering? I am sure there is a better way to do it (besides just it not working…), but I am not grasping it in my research.

Thanks for your help.

BCBB

3

Answers


  1. You can use a watcher instead of using computed property it will perfectly fit in you scenario:

    Watcher official docs

    In your case you can watch your load_list data property. when whenever any change happen in load_list then that watcher will run.In the watcher by comparing your values combinations you can set your listLoaded (which you should need to declare within the data())

    Example watcher code of your scenario
    
    watch:{
       //whenever load_list changes, this function will run
    
       load_list:{
        handler(newList, oldList) {
          let isLoaded= newList.every((x) => x)
    
          if(isLoaded){
            //code here 
          },
        }
       }
     },
    
    

    I hope that will help you.

    Login or Signup to reply.
  2. const vm = new Vue({
      el: "#root",
      data() {
        return {
          list1: [false, true],
          list2: {
            0: false,
            1: true
          }
        }
      },
      computed: {
        load1() {
          return this.list1.every(it => it);
        },
        load2() {
          return Object.values(this.list2).every(it => it);
        }
      },
      methods: {
        handler1() {
          Vue.set(this.list1, 0, true);
        },
        handler2() {
          this.list2[0] = true;
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="root">
      <div>
        <div>
          <div v-if="load1">All true</div>
          <button type="button" @click="handler1">Array</button>
        </div>
        <div>
          <div v-if="load2">All true</div>
          <button type="button" @click="handler2">Object</button>
        </div>
      </div>
    </div>

    Due to limitations in JavaScript, there are types of changes that Vue cannot detect with arrays and objects. These are discussed in the reactivity section.

    See

    Login or Signup to reply.
  3. how about usd componentkey

    <b-container v-if="load_list.every((x) => x)" :key="componentKey">
    
     function() {
          API.getActor(this.id)
            .then(a => {
              this.getActor(a)
              this.componentKey++
            })
            .catch(error=> console.log(error))
            .finally(() => {
              this.load_list[0] = false
    
            })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search