I've been using Vue heavily for a while now and this week I ran into an issue that I've never seen before. It's something documented and pretty well known (when I tweeted about it I got a reply in about 60 seconds) but I just had not hit it before. Before I get into $nextTick, let me explain what I was doing and what went wrong.

I have a hidden form on a page that needs to have a dynamic action value. Consider this markup:

<div id="app" v-cloak>
  <form :action="myAction" method="post" ref="myForm">
    <button @click.prevent="testAction">Test</button>
  </form>
</div>

And this code:

Vue.config.productionTip = false;
Vue.config.devtools = false;

const app = new Vue({
  el:'#app',
  data: {
    myAction:null
  },
  methods:{
    testAction() {
      this.myAction = 'http://www.raymondcamden.com';
      this.$refs.myForm.submit();
    }
  }
})

Looks simple enough, right? Probably the only interesting thing here is the use of ref and this.$refs to handle accessing the DOM directly with Vue. I call it fancy because it isn't something I usually need to do with Vue. So what happens when you test this? Try it yourself and see:

See the Pen what the tick?!?! by Raymond Camden (@cfjedimaster) on CodePen.

Instead of POSTing to my server, it sends the POST directly to CodePen, and just today I discovered they support echoing back the data which is kind of cool! (Note, in the embedded CodePen above, the POST echo doesn't work. It may not be a feature of the embed.)

Alright, so what the heck went wrong? Well, if you're like me, you may not have read the "Internals" section of the Vue.js documentation, specifically this part: Async Update Queue.

In case you haven’t noticed yet, Vue performs DOM updates asynchronously.

Raise your hand if you hadn't noticed this yet.

Ray raising his hand

Luckily there's a simple fix for this and if you actually read the title of this post, you have an idea of what it is: this.$nextTick. This function lets you provide a callback to execute when Vue is done propagating your changes to the DOM and it's safe to assume it reflects your new data. The fix is pretty simple:

this.$nextTick(() => this.$refs.myForm.submit());

And if fat arrow functions still confuse you a bit (nothing wrong with that!), here's a simpler version:

this.$nextTick(function() {
	this.$refs.myForm.submit();
});

You can see the corrected version in the CodePen below.

See the Pen what the tick?!?! (fixed) by Raymond Camden (@cfjedimaster) on CodePen.

So to answer the question of "when" - I guess I'd say when you need to ensure the DOM 100% reflects your data and in this case it's kind of obvious - I needed my form POST to use the correct URL. Out of all the times I've used Vue this is the first time I needed this precise level of control but I'm sure I'll run into more examples. If you can, please share an example of when you've used it in the comments below!

Header photo by Franck V on Unsplash