Another Vue Example - Image Recognition Service Tester

This weekend, I did some work updating my little Node-based image recognition service tester testing tool. The back-end is built in Node with a front end using vanilla JavaScript and Handlebars. I thought it would be interesting to see what it would be like to re-write the code in Vue. To be clear, nothing was broken so this was a completely arbitrary decision, but as I wanted an excuse to write some more Vue, I figured it was a good idea. As I’ve said though - keep in mind I’m still learning how to use Vue so what follows will probably not be “ideal” code.

Old Version

Let’s start by quickly discussing the “old” version. I’ve got old in quotes there as this project is only a few months old. As I said, it was vanilla JavaScript and Handlebars, nothing too terribly complex. The front end HTML looked like so - with a lot cut out for space:

In the above code sample, you can see a “main” body template followed by a script tag used for the Google rendering template. I cut out the three other script blocks to save space as well as some of the Google one as well. But the basic “form” of the page was:

html for the page with empty divs for each report
a hidden template for Google
a hidden template for IBM
a hidden template for Microsoft
a hidden template for Amazon

I could have done that better. Handlebars lets you build your templates in their own files and then use the CLI to compile them into functions. This saves space both on the HTML and execution time of JavaScript as well as it can skip “parsing” your template. (You can view the entire version of the template here).

On the JavaScript side - it was mainly DOM manipulation. I’d upload the image, call the Node code, and then pass the data to the compiled Handlebars templates. There was a lot of “hide this”/”show this” going on, but Handlebars pretty much took the data as is. I did one small bit of manipulation for something with Microsoft’s service, but that was the exception.

You can see just how much is handling grabbing DOM elements and changing them.

To be clear, I’m not saying this is bad per se, and it wasn’t difficult without jQuery at all. But let’s consider the Vue version.

The New Vue

(Can you guess how long I’ve been waiting to use that phrase?)

I began by creating a JSON export of my Node code’s results so I could test more quicker. I then began working on JavaScript. One of the first things I ran into was handling the form and the image preview. As a reminder - the code lets you select an image with a regular input/file field and then render a preview. Only after you upload does processing begin. I quickly discovered the v-model doesn’t work with input/file fields as they are read only. This is what I ended up with.

I’ve got a change handler on the file field to do the ‘auto preview’ thing and I’ve attached a submit handler to the form. The addition of .prevent means that Vue will handle preventing the default form submission thing for me. (Yet another reason I’m falling in love with Vue.) Here is the beginning of the JavaScript as well as the two handlers involved with the form.

For the most part, this is the same as before, except that I’ve attached the handlers to my Vue object. The actual rendering is done in another method, but as I don’t call that method anywhere else, it should probably be folded into doForm, but I like the seperation a bit so I’m happy with it. Here’s that method:

So in theory - I could have maybe just did something like - “for x in data, this[x] = data.x” - but the more specific checks felt… I don’t know. Not better, but ok for now. If you remember, in my last update I made it easier to disable services so it’s definitely possible .amazon or .ibm won’t be there. And that’s it for the JavaScript code. The entire file (found here) is now 69 lines, roughly half the lines of the previous version (136). Biggest thing missing are all (or most) the calls for DOM manipulation.

The front end HTML now has the templates “inside” the body as Vue is going to mark it up as is. Again I don’t want to share the entire template as it is pretty long (although it did get smaller compared to the first version), so here is the same “cut” as before.

For the most part, the conversion from Handlebars to Vue was straight forward. I screwed up a lot at first, but I was incredibly impressed by the error messages Vue spit out. In nearly every single case, it was obvious what I had done wrong and what I had to do to fix it. The only thing that threw me was an inline style:

It took me a bit to figure out that my CSS property had to go from background-color to backgroundColor. The error message told me I had invalid syntax, but I just couldn’t figure out what was wrong with it.

All in all - I much prefer v-for over {{#each something}}. On the other hand, this form really wigs me out a bit:

Anyway - I hope this sample is helpful to others. The entire code base is up on GitHub - https://github.com/cfjedimaster/recogtester. Feel free to suggest improvements to my use of Vue - I’m new so I won’t mind. ;)

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos.
If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.