MVC will really help you debug your code faster

Arthur Guiot
5 min readMay 20, 2018

Even the best developers in world are doing mistakes. And the debug can cause them headaches for weeks.

Code is hard to debug because it's not a spoken language, I mean by that that code is very strict and while in a spoken language, structure is not the most important, in code the structure is probably the most important thing because your compiler / linter will help you fix spelling issues.

Here is an example of what I meant:

In English, a beginner may write something like:

I wante too hit

I may exaggerate, but you’ll be able to understand what he’s saying.

But In code if you write something like:

want I to eat

The interpreter will just go like that:

WTF?

And it will be impossible for a beginner to fix this issue, because each words are spelled correctly.

As a JavaScript developer (I know other language, but I’ll focus of JS here because it’s the most famous one), debugging can be hard, especially when I didn't write the code, because most people don’t care about the structure and write code like:

This code is for form validation

const divs = new Array();
divs[0] = "errFirst";
divs[1] = "errLast";
divs[2] = "errEmail";
divs[3] = "errUid";
divs[4] = "errPassword";
divs[5] = "errConfirm";
function validate() {
const inputs = new Array();
inputs[0] = document.getElementById('first').value;
inputs[1] = document.getElementById('last').value;
inputs[2] = document.getElementById('email').value;
inputs[3] = document.getElementById('uid').value;
inputs[4] = document.getElementById('password').value;
inputs[5] = document.getElementById('confirm').value;
const errors = new Array();
errors[0] = "<span style='color:red'>Please enter your first name!</span>";
errors[1] = "<span style='color:red'>Please enter your last name!</span>";
errors[2] = "<span style='color:red'>Please enter your email!</span>";
errors[3] = "<span style='color:red'>Please enter your user id!</span>";
errors[4] = "<span style='color:red'>Please enter your password!</span>";
errors[5] = "<span style='color:red'>Please confirm your password!</span>";
for (i in inputs) {
const errMessage = errors[i];
const div = divs[i];
if (inputs[i] == "")
document.getElementById(div).innerHTML = errMessage;
else if (i == 2) {
const atpos = inputs[i].indexOf("@");
const dotpos = inputs[i].lastIndexOf(".");
if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= inputs[i].length)
document.getElementById('errEmail').innerHTML = "<span style='color: red'>Enter a valid email address!</span>";
else
document.getElementById(div).innerHTML = "OK!";
} else if (i == 5) {
const first = document.getElementById('password').value;
const second = document.getElementById('confirm').value;
if (second != first)
document.getElementById('errConfirm').innerHTML = "<span style='color: red'>Your passwords don't match!</span>";
else
document.getElementById(div).innerHTML = "OK!";
} else
document.getElementById(div).innerHTML = "OK!";
}
}
function finalValidate() {
let count = 0;
for (i = 0; i < 7; i++) {
const div = divs[i];
if (document.getElementById(div).innerHTML == "OK!")
count = count + 1;
}
if (count == 6)
document.getElementById("errFinal").innerHTML = "All the data you entered is correct!!!";
}

Without running the code, can you figure out what is the mistake?

But the cool thing with MVC is that code gets a lot more cleaner to read, so the debugging process is a lot faster.

By separating task, if you see that a part of your website doesn't work, you can immediately identify where is the issue, and start debugging efficiently.

How to implement MVC in JavaScript?

There is a range of MVC framework out there, but I’m going to focus on ProType, a relatively new MVC framework (that I created) that resemble to what we get in other languages such as Swift.

Here is a simple example of an app to display the time, either by using a digital clock or a watch face, using ProType:

First, let’s do the HTML (in the <body> tag)

<select class="select">
<option value="clock">Clock</option>
<option value="watch">Watch</option>
</select>

<div class="view" protype="clock">
<h1>Clock</h1>
<div class="group">
<div class="h item"></div>
<div class="m item"></div>
<div class="s item"></div>
</div>
</div>
<div class="view watch" protype="watch">
<h1>Watch</h1>
<div class="watchGroup">
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
</div>

Then we’ll do the CSS:

h1 {
font-size: 64px;
}

.view {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
box-sizing: border-box;
padding: 100px;
text-align: center;
background: white;
}
.view .group {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.view .group .item {
color: white;
font-size: 56px;
width: 20vw;
height: 20vw;
margin: 20px;
line-height: 20vw;
vertical-align: middle;
text-align: center;
background: #292929;
}

.watchGroup {
background-color: #fff;
height: 250px;
width: 250px;
border-radius: 50%;
}
.watchGroup::before {
content: " ";
width: 20px;
height: 20px;
position: absolute;
background-color: #161C2E;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.watchGroup span {
height: 80px;
display: block;
position: absolute;
width: 7px;
background-color: #222;
transform-origin: 50% 100%;
bottom: 50%;
left: calc(50% - 4.5px);
transition: all 500ms ease-in-out;
}
.watchGroup span.hours {
width: 8px;
height: 60px;
left: calc(50% - 6px);
}
.watchGroup span.seconds {
width: 5px;
left: calc(50% - 2.5px);
height: 85px;
transition: all 0ms;
}
.watchGroup span.current {
width: 0px;
left: 37.5%;
}

.select {
position: absolute;
top: 30px;
left: 40vw;
right: 40vw;
margin: 0 auto;
text-align: center;
z-index: 100;
}

@keyframes ClockToWatch {
from {
transform: translateX(0);
}
to {
transform: translateX(-100vw);
}
}
@keyframes WatchToClock {
from {
transform: translateX(0);
}
to {
transform: translateX(100vw);
}
}

And now, the JavaScript:

We’ll start by creating a ProType instance:

const P = new ProType()

And we’ll create the clock Group:

class Clock extends P.Group {

changeHandler(state) {
this.h.innerHTML = this.state.hour
this.m.innerHTML = this.state.min
this.s.innerHTML = this.state.sec
}
setTime() {
function paddingZeros(n) {
return n < 10 ? "0" + n : n
}
const now = new Date()
const h = paddingZeros(now.getHours())
const m = paddingZeros(now.getMinutes())
const s = paddingZeros(now.getSeconds())
super.setState({
hour: h,
min: m,
sec: s
}, this.changeHandler.bind(this))
}
init() {
this.state = {}
this.h = this.group.querySelector(".h")
this.m = this.group.querySelector(".m")
this.s = this.group.querySelector(".s")
this.i = setInterval(this.setTime.bind(this), 1000 / 30)
}
}

Now, we can create the clock View, and mount the Group:

class ClockView extends P.ViewController {
willShow() {
this.g = this.mountGroup(this.view.querySelector(".group"), Clock)
}
willDisappear() {
clearInterval(this.g.i)
}
}

After, we’ll create the watch Group:

class Watch extends P.Group {
changeHandler() {
this.s.style.transform = `rotateZ(${this.state.sec}deg)`
this.m.style.transform = `rotateZ(${this.state.min}deg)`
this.h.style.transform = `rotateZ(${this.state.hour}deg)`
}
setTime() {
function paddingZeros(n) {
return n < 10 ? "0" + n : n
}
const now = new Date()
const h = paddingZeros(now.getHours())
const m = paddingZeros(now.getMinutes())
const s = paddingZeros(now.getSeconds())
super.setState({
hour: (h / 12) * 360,
min: (m / 60) * 360,
sec: (s / 60) * 360
}, this.changeHandler.bind(this))
}
init() {
this.state = {}
this.s = this.group.querySelector(".seconds")
this.m = this.group.querySelector(".minutes")
this.h = this.group.querySelector(".hours")
this.i = setInterval(this.setTime.bind(this), 1000 / 30)
}
}

And we can create our View:

class WatchView extends P.ViewController {
willShow() {
this.g = this.mountGroup(this.view.querySelector(".watchGroup"), Watch)
}
willDisappear() {
clearInterval(this.g.i)
}
}

After we created all these class, we can tell ProType to mount them:

P.autoMount(ClockView, WatchView)
P.set("clock")

To finish, we’ll just add to the <select> tag an event listener so we can switch between Views:

document.querySelector(".select").addEventListener("change", e => {
const index = e.target.selectedIndex
if (index == 1) {
P.performTransition(e.target.options[index].value, {
animation: "ClockToWatch",
duration: "500ms"
})
} else {
P.performTransition(e.target.options[index].value, {
animation: "WatchToClock",
duration: "500ms"
})
}
})

Pretty easy right? I know that for a beginner, it might seems really hard, and that I could have chosen a better example to illustrate my point, but I think that even a beginner can understand that managing each element individually reduces the probability of having a bug.

--

--

Arthur Guiot

Student by day, developer by night. Traveler by nature, Motorsport fan.