Search code examples
javascriptvue.jsprintingreactive-programming

How to check view rendered after get data from API Vue JS


I have a problem with getting data from the API using VUE JS and then I want to print this page. After I got data from API, Elements did not completely render and the print option popped up with the blank data in the page. It worked with the setTimeout function, but it did not work perfectly with all my clients. If I want to work perfectly with all my clients I will set a long waiting timeout. It is a bad solution.

methods: {
            getData() {
                axios.get('/api/sale/receipt/' + this.$route.params.uuid).then((res) => {
                    this.sale = res.data
                    if(this.sale.customer == null) {
                        this.sale.customer = {}
                    }
                    
                    $('.main-loader').hide();
                    // setTimeout(function() {
                        window.print();
                        window.close();
                    // }, 2000);
                }).catch((res) => {

                });
            }
        },

So after the elements rednerd print options will popup. Thanks


Solution

  • Here is an example of using $nextTick() in Vue.

    If you use window.print() directly, without $nextTick() then you will not get the list of posts in your print, since it takes time to update the DOM.

    const { createApp, ref } = Vue 
    
    const App = {
      data() {
        return { 
          posts: [] 
        }
      },
      created() {
        this.getData();
      },
      methods: {
        getData() {
              fetch('https://jsonplaceholder.typicode.com/posts')
                  .then((response) => response.json())
                  .then((data) => 
                  {
                    this.posts = data;
                    this.$nextTick(() => {
                      window.print();
                    });
                  });
          }   
      }  
    }
    
    const app = createApp(App)
    app.mount('#app')
    #app { line-height: 1.75; }
    [v-cloak] { display: none; }
    <div id="app" v-cloak>
    <div v-for="post in posts" :key="post.id">
      <label>Id:</label>{{post.id}}<br/>
      <label>Title:</label>{{post.title}}<br/>
      <label>Body:</label>{{post.body}}<br/>
      <hr/>
    </div>
    </div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>