|

Working with time Time is painful - Photo by Aron Visuals on Unsplash

Let’s start by pointing out the obvious. It is painful to work with dates. No matter the technology, it is just harder than it should be.

Anyway… I stumbled across one of those annoying date related issues with axios. Just to be fair, the problem is not necessarily an axios problem, I just got to it when using axios. By default, axios will use JSON.stringify to convert an object to a json. Nothing fancy here. The problem is that when a date object is sent to the server, it will be converted to UTC and one might not necessarily want that.

In reading axios documentation, the recommendation was to provide the transformRequest which allows for complete control of the serialization. While that would certainly work, it is a lot of work to just to handle dates in a different way.

The simpler solution to this is to simply overwrite the toJSON function of the Date prototype. Like so:

This works because internally, the JSON.stringify function will call toJSON. Objectively, you could do this to any prototype, although none of the other types are as annoying as Date to work with.

Cheers, Lucas

|  

Dirty rugby match This match is dirty - Photo by Quino Al on Unsplash

Ever filled up a form with a bunch of information and then accidentally navigated away and lost all data? Well, that’s frustrating. However, as a developer, it might be tricky to implement such functionality. This post is a practical guide to implementing is dirty checking using Vue, Vue Router and Typescript.

TL;DR

Code is available on GitHub.

Expected behavior

In a Vue app with Vue Router, when a user modifies data in a form and any navigation to another route occurs, the user should be notified and have the ability to cancel navigation.

Is Dirty Demo Demo app running

FormEdit.vue

I like to wrap this kind of functionality in base components that can be reused across multiple forms. This is specially true for IsDirty and IsBusy. For this demo I created a FormEdit component.

The FormEdit component will be added inside a template to wrap the form controls. It will also request that the entity being edited is passed to it so it can track changes using a @Watch. Finally, it exposes two methods to control is dirty and navigation: resetDirty will be called anytime the consumer deems the entity to be clean; ensureNotDirty will be called anytime navigation is detected from its parent component registered as a route in Vue Router.

Home.vue

This component contains the actual form with a couple of fields. It uses the form-edit as a wrapper around the form fields as indicated in the previous section. On mounted we load the data and mark the form as not dirty. This is required because by modifying the entity property the FormEdit thinks the form is dirty. Finally, this component has a hook for beforeRouteLeave. This hook is what we need to intercept and allow or cancel the navigation. The heavy lifting is done by FormEdit but Vue Router requires that the route component has the hook method meaning that we intercept it here and pass the values on the FormEdit.

Can we improve this?

Of course! The number one thing you might want to do is to replace the simple dirty tracking with an actual compare of the old/new entity so you only prompt the user if they have changes pending. Once the user changes the record back, you can disable save button and such.

Got some feedback for me? Hit me up on twitter!

Cheers, Lucas