You might not know about me that I have conducted tech interviews with over 500 software developers from more than twenty countries with the objective of identifying and hiring the best talent. I have also been in the candidate position, interviewing for positions ranging from junior developer to CTO.
In this series, I am exposing the secrets of JavaScript interviewing. You will get a chance to solve a tech interview exercise every single week. You will not only refresh your JavaScript skills, but above all, you will learn the mindset required for solving interview exercises. We will start with simple tasks, and then transition to complex exercises that you could even use to build your portfolio.
Exercise
Refactor the Pomodoro App from the previous exercise such that your tasks will be placed on cards, not table rows. Use the block-element-modifier syntax in your CSS and emphasize separation of concerns. Take care of the styling of the application as well as the functionality.
You have a free choice in your design decisions.
Imagination, life is your creation
This time, you are the freelancer, and you are supposed to drive all design decisions. If you don’t know what you are doing, check out tools that have solved the same problem. In order to save your time, I suggest searching for screenshots of Trello and KanbanFlow boards. Don’t worry, you don’t have to implement a full board… yet. We are just focusing on one column.
Let’s start with creating the markup for our column:
<div class="task-column">
<div class="task-column__header">Tasks</div>
<div class="task-column__body js-task-column">
<div class="task js-task" data-id="0">
<span class="task__name">Write Article</span>
<span class="task__pomodori">0 / 2 pomodori</span>
<div class="task__controls">
<span class="task-controls__icon js-task-done"></span>
<span class="task-controls__icon js-increase-pomodoro"></span>
<span class="task-controls__icon js-delete-task"></span>
</div>
</div>
</div>
</div>
Notice the block-element-modifier syntax. A container is connected to an element via __
. We can only use one __
in a class name, som instead of task__controls__done
, we just used task-controls__done
. We could attach modifiers to these classes with --
. Block-element-modifier classes should not be referenced in our JavaScript code. They are for styling purposes only. This is how we achieve separation of concerns.
Let’s style the elements.
.task-column {
width: 20rem;
background-color: #ccc;
border: 1px #333 solid;
}
.task-column__header {
width: 14rem;
margin: 1rem 1rem 0 1rem;
padding: 2rem;
background-color: #777;
color: #eee;
text-align: center;
font-size: 1.5rem;
}
.task-column__body {
width: 16rem;
margin: 0 1rem 1rem 1rem;
padding: 0.8rem 1rem;
background-color: #999;
min-height: 2rem;
}
.task {
width: 12rem;
height: 3rem;
margin: 0.5rem 1rem;
background-color: #eee;
padding: 1rem;
user-select: none;
}
.task__name {
display: block;
}
.task__pomodori {
display: inline-block;
float: left;
}
.task__controls {
display: inline-block;
float: right;
}
.task-controls__icon {
cursor: pointer;
}
I will not get into the details of explaining each rule. Understanding CSS is a lot easier than JavaScript, you can reverse engineer each rule with some googling. Some minimal styling knowledge always comes handy.
Let’s connect the markup with the JavaScript code. First of all, let’s delete the static tasks from the markup:
<div class="task-column">
<div class="task-column__header">Tasks</div>
<div class="task-column__body js-task-column">
</div>
</div>
In the JavaScript code belonging to the previous example, let’s replace js-task-table-body
with js-task-column
on line 3. Let’s also replace the variable name pomodoroTableBody
with pomodoroColumn
.
const pomodoroColumn = document.querySelector( '.js-task-column-body' );
Don’t forget to replace all occurrences of pomodoroTableBody
with pomodoroColumn
in the code.
We have one task left: let’s rewrite the renderTasks
function to generate the new markup structure:
const renderTasks = function( tBodyNode, tasks = [] ) {
tBodyNode.innerHTML = tasks.map( ( task, id ) => `
<div class="task js-task" data-id="0">
<span class="task__name">${task.taskName}</span>
<span class="task__pomodori">${task.pomodoroDone} / ${task.pomodoroCount} pomodori</span>
<div class="task__controls">
${ task.finished ? 'Finished' : `
<span class="task-controls__icon js-task-done"
data-id="${id}">\u{2714}</span>
<span class="task-controls__icon js-increase-pomodoro"
data-id="${id}">\u{2795}</span>`
}
<span class="task-controls__icon js-delete-task"
data-id="${id}">\u{1f5d1}</span>
</div>
</div>
` ).join( '' );
}
We are done.
There was not much JavaScript in this task. I included it, because it is important to emphasize that in frontend and full stack development, you need to be competent in refactoring markup and add some basic CSS. In some occasions, you also have to showcase your creativity and grit by taking the initiative and designing the interface of your applications.
Learn ES6 in Practice
Sign up below to access an ES6 course with many exercises and reference solutions.
Now that we have solved this exercise together, don’t forget that there are four pillars for a successful tech interview:
- Tech skills
- Problem solving skills
- Soft skills
- Personal Branding
This blog addresses the first two skills. My other blog, devcareermastery.com addresses soft-skills, and my book The Developer’s Edge – How to Double Your Career Speed with Soft-Skills helps you with soft-skills as well as with your personal brand.
If you are interested in fine-tuning your JavaScript skills as well as your soft skills, I highly recommend that you consider purchasing The JavaScript Developer’s Career Bundle. This bundle contains my book ES6 in Practice, 4.5 hours of JavaScript videos, and The Developer’s Edge. You will not only be fully up-to-date with the latest version of JavaScript, but you will also learn how to build a fulfilling career for yourself.