Dear email HTML, please get better

i hate email html banner with a cat with mouth open wide looking unhappy
Photo by Erik-Jan Leusink on Unsplash

I dislike email HTML. There, I openly said it! I really had to get that out of my system before I go crazy.

One of the crowning achievements in my short software development career so far is having built a drag and drop email editor for Metisa in React.

It’s not perfect but it means something to me because I consider it to be the first real feature I’d developed and deployed to a live product with actual users.

While I thoroughly enjoyed the process of figuring out how to build a WYSIWYG (what you see is what you get) email campaign builder, I disliked the part where I had to figure out how to make it output HTML that would be compatible with over 70 email clients on multiple devices with different operating systems (surprise). Entire businesses have been built on how hard it is to get an email to look right on all devices.

Continue reading “Dear email HTML, please get better”

Writing my first Sass mixins

writing my first sass mixins banner
Photo by Dmitri Popov on Unsplash

Sass is a CSS pre-processor. Even though I’ve been using Sass in many projects, I realised recently at work that I’d only been using it in a very primitive way. Sass mixins didn’t even exist in my mind.

The main ways I’d been using Sass are:

  • declaring variables in a single file as the main way of easily configuring an entire project
  • extending/inheriting selectors to reduce repetition (to keep the code DRY)
  • nesting selectors to create and maintain a clear visual hierarchy

But there’s an incredibly useful feature of Sass that I’d been missing out on. I only accidentally stumbled onto it recently – it’s called Sass mixins.

Continue reading “Writing my first Sass mixins”

How to tunnel HTTP requests into localhost

ngrok explanation illustration

Suppose you’re part of the engineering team of a tech company whose product is involves giving users product recommendation widgets for online stores. Since the product is already in the wild, so to speak, how do you test developmental features on live stores?

Continue reading “How to tunnel HTTP requests into localhost”

You don’t know everything

By you I mean I. I’m ready to admit, I don’t know everything.

It’s an admission that doesn’t cause me to blush but makes me feel stronger. By acknowledging how little I know, I’m motivated to find out more about a topic.

With a few months of work as a software engineer under my belt now, I have a good sense of my standing among other software engineers in the field. Form a technical standpoint, I’m far from good. I mean on a scale of 1 to 10, with 1 being practically useless, I think I’m at 5 – not completely useless but still having a lot to learn.

Now that’s an admission you won’t see very often, especially if that person is looking to climb the professional ladder…

But I think it’s important and necessary to be truthful to yourself once in a while.

On most days you can “hustle” and pretend that you got your shit together and can do these amazing things. That brings with it numerous benefits, like better team morale, higher likelihood of having the person on the opposite end of a business transaction partially fooled, and an overall sense of self satisfaction. It’s good and it’s necessary, since we’re all imposters in some ways until we are not.

But I deeply believe that in the occasional moments when we are truthful to ourselves, we make the most progress, personally and professionally.

So allow me to admit that I’m not that good a software engineer yet. To be specific, based on my recent experiences at work, I know I need to work these specific areas:

  • Embracing a different language and framework from what I’m used to (Python and Django)
  • Being able to tell in at least half of all decision-making occasions whether Approach A or B is going to be a better decision down the road
  • Bridging the gap between my typing and thinking speeds so I can create features and fix bugs quicker (I think much slower than I can type at 105 WPM)

Now I have a list. Great, another list!

I’m being half sarcastic there. Only half.

I believe in lists and know a few good people who do too. Lists make concrete the floaty “I think”s, which in turn makes it possible for me to break through them.

With this list what I’m going to do is to break it down further into sub-lists. For example, I’ll make a list of things that answers this question: what’s stopping me from embracing Python and Django?

  • The syntax looks different from JavaScript
  • Resentment towards the fact that if we used NodeJS instead of Django on the project, I’d be able to code entirely in JavaScript (this is funny because I once lamented how difficult it is to set up a NodeJS server)
  • Not knowing enough to write code without having to cross- and double-check everything in the documentation and existing code

And then from there I’m going to come up with questions, this time as specific as possible, that would help me overcome this sub-list:

  • Why do you need to import so many basic features in Python? (I have a hunch for this answer, but knowing the philosophy of Python’s creators might offer insights into how I should be thinking about the language)
  • Why are Django controllers called views? That really confuses the shit out of me and I know I’m definitely not alone
  • What mental hacks can I use to convert my mind to thinking in Django’s terms?
  • Why do I need to deal with Serializers in Django when I don’t have to in a similar framework like Ruby on Rails?
  • What does class Meta: do in a Django model?
  • How exactly do you set up a REST API in Django REST Framework?
  • What’s the easiest way to pretty-print things in Terminal when working in Python and Django?

Man, the list is long!

But that’s how you know you know nothing. Jon Snow.

Perhaps it might be helpful to other software engineers looking for answers to these questions, so I intend to share my findings in another post. Enter your email in the box in the right panel to get notified to come read it when it’s out.

What it’s like building app features in 2017

First of all let me admit, I wasn’t there to witness what it was like to build web/mobile app features before 2016, since I only became a web developer last year.

That said, seeing that the open source movement really only picked up amazing momentum in the past couple of years, I can imagine that it was much harder to build full-fledged features from the ground up till as late as early 2010s. That difficulty is also probably exacerbated by the less nimble management practices of tech companies (agile wha-?) and the overall economics of hiring developers to build software.

But this is 2017, and I now have the vantage point of being a developer / software engineer that affords me some insights into what it’s like building app features now.

I’m writing this article on the same day that I created a pull request to submit my last two and a half weeks worth of work. The work was for a drag and drop email editor user interface, built mainly with ReactJS, and I’m really happy to complete my first major feature ever for a live product! Although I was a little overly optimistic and ended up delivering about half a week behind schedule…

Over the course of building this feature I’ve learned a few things about software development, some general and some more specific to current times. Some of the more interesting ones:

  • There are a lot of great open source software that anyone (companies and individuals) can use for free now
  • Using an open source library also means trusting the creators/maintainers enough to make our project dependent (reliant?) on theirs
  • Software developers have to be like surgeons when building features on top of an existing code base

More on the point about free, open source software available out there in 2017. In the process of building the email editor feature, I used three open source libraries that I think are really well made, and for which I’m incredibly appreciative of. QuillJS, react-quill and react-dnd helped me ship the feature in two and a half weeks.

Now I know that I mentioned that I shipped this feature about half a week late, but just pause for a moment and appreciate how short that timeframe is. In less than a month, one person was able to write the code that powers a Wix-like drag and drop editor for composing emails that all users of our product can make use of. While it’s probably still buggy to some degree, it’s definitely ready for use.

This is the environment we operate in now. Regardless of what it was like building software before 2017, I’m grateful to be alive and contributing to the software industry now. The collaborative atmosphere in the software community doesn’t just make me feel warm and fuzzy, it actually helps me do my job better!

How programmers work together from every part of the world

The label ‘digital nomad’ exists because people whose job was to write programmes have become so fluid in the workplace that they can work from virtually anywhere in the world on the single, simple condition that there is an internet connection.

With Dropbox as ubiquitous as it is nowadays, it might be easy to overlook just how difficult it is for multiple ‘devs’ (short for developer) to work on a single project at the same time. But think about it: what happens when your friend works on the same Word document on Dropbox as you are right now, and saves her file?

Conflict, right? Dropbox’s programme will detect the conflicts and automatically save one copy—your friend’s or your copy, depending on circumstances—as a “conflicted copy”, for you to sort out later and merge them manually.

Programmers, being programmers, use a much more sophisticated versioning protocol and software. It’s called Git (pronounced as ‘geet’)- and it is the utility that empowers programmers to work remotely with one another. It is also the single biggest enabler of the open source movement. Here, I’m going to go into the technicalities for a bit so if you’re not interested in that kind of thing, feel free to drop out now!

Git is a version management software that handles the complex distributed workflow of distributed teams. While it’s powerful, it is also quite difficult to grasp at the beginning. But as with any tool, once you understand how to use it, life becomes much less burdensome.

Every web project has many files, sorted into various folders like ‘css’, ‘javascript’, and ‘images’. This isn’t far from the projects most of us are already used to. What’s different is the fact that in a file that contains code, like ‘main.js’, which contains JavaScript code, lines are linked to one another through what is written.

If someone makes changes from line 12-20, that change might have a ripple effect on every other line, and if this is not updated in the second programmer’s computer in time, and the programmer starts to work on the now-outdated version of the project, things can get chaotic very quickly. Bugs will crawl throughout the programme…

That’s one of the many situations where Git saves the day. Let’s say I’m the first programmer mentioned above:

I would execute the above commands (each line being one) in my command line interface (Terminal for Mac) to synchronise my work to the cloud. Broken down, it goes something like this:
– Save my code on my computer (cmd + s)
– Put the changed files into a figurative cart (git add .)
– Pass the cart through the cashier who will write in her logbook the message “Created resetButton function to reset game” (git commit -m …)
– Strap the cart to a rocket and launch it into the clouds. (git push origin master)

Once this is done, the latest version of our team project is on Github. Let’s say now I’m the second programmer…

The only the difference is that I now have to enter the command git pull to fetch the latest version before starting work.

What happens if programmers 1 and 2 are both working on the file at the same time, at 10:30pm on a Saturday night? This is when things can get tricky. Thankfully, Git makes the process much simpler.

Git is smart, so it will look compare the files that a programmer pushes into the repository (hosted on Github) with the ones originally in the repository, which are now outdated.

If programmer 1 finishes work first, he will push his changes to the repository without obstacles (assuming only two of them are working on the project at this time). But when programmer 2 finishes his work 30 minutes after that, a problem arises – programmer 1’s work, which did not exist in the file when programmer 2 started, is now the updated version on the repository on Github. So what happens when programmer 2 tries to send his finished work to Github?

This is the part that differentiates Dropbox from Git – instead of accepting both copies and renaming one as a ‘conflicted copy’, Git will see the discrepancy and prevent programmer 2 from being able to git push to the repository! Instead, he’s prompted to do a git pull to retrieve the latest version of the project. What happens now?

Programmer 2 now has two versions of the project. Without Git, he’d understandably be at a loss, confused over what to do. But Git knows a bit of magic – when a file has edits that are different from the one in your computer, it attempts to auto-merge them. To achieve this Git actually compares the contents of each file with one another. If the file that both programmers worked on has a total of 800 lines and programmer 1 worked on lines 1-200 and programmer 2 added lines 800-1000, Git would very likely understand that as work on two separate parts of the project and, without bothering the programmer in question, add them both to a single, merged file automatically. Isn’t that wonderful?

Of course that leaves with us a few other situations that are a little less magical. If a conflict occurs (say, Git detects that you’ve both been working on the same lines of code), what needs to be done to restore order?

I’m afraid Git can’t make decisions of which version of a block of code to retain and which to discard – that responsibility is too heavy to carry, I suppose. The programmer who receives the conflict (programmer 2 in our case, who finished his part of the work 30 minutes after his partner) must resolve the conflict manually.

That said, Git inserts markups into the file with both versions of a block of code—one that programmer 1 worked on and the other by programmer 2—that visually delineates the two versions for ease of comparison by the programmer who is doing the de-conflicting. So programmer 2 has to delete the lines of code that he knows are old, save, and upload that final copy to Github. Order will then be restored.

Is it overly complicated? At this point I’d say it isn’t. Even though I think I haven’t used half of its features, I’ve used some of the most frequently used ones and so far, it enhances my workflow as a solo programmer and on a small team that is physically close. When I eventually work on a remote assignment, I can see how Git and Github will make things smoother and make my life as a programmer slightly easier.

Quick deployment via Github Pages

Finally, I also learned about a Github feature called ‘Pages’ today. I’ve been using Codepen to do what it does so far, which is to deploy a project to the web so that it is accessible to more than just, well, my local machine.

Pages seems to offer more convenience, since deployment is executed directly from the command line rather than a web interface, but I’ll have to play around with it before giving my verdict. For now though, I like how cleanly it deploys my project online without the bells and whistles that Codepen presents by default (like the Editor view, which allows any visitor to see the source code that may taint the user experience).

Github Pages is only suitable for projects that don’t need custom server-side code!

Getting stretched

I’m going to keep this post short because I think tonight’s homework is going to take over 3 more hours…

Yesterday was day 1 of our web development immersive course at General Assembly Singapore. I found ourselves off to a slow start. Perhaps someone from the instructional team had read my blog (though I really doubt it) and decided to kick things up two notches, because one of today’s assignments may look easy but in reality, they are anything but.

First one was easy enough: code a simple blog with two entries, hard coded. (Hard coded means written explicitly in HTML, rather than having a way to create new post entries dynamically through user input.) I did this:

mock blog screenshot

Right after that project, which I now think was meant to be warm up, Steve went through a large number of CSS syntax with us. Though by no means exhaustive, I believe he went through just enough to justify throwing us into the deep end with the next two assignments:
– Recreate Instagram’s landing page
– Recreate Airbnb’s landing page

I started with Instagram’s, but I struggled for a long time just trying to get the CSS file (style.css) to be properly linked to the HTML file (index.html). Turns out, I used href=“/css/style.css” instead of href=“css/style.css”. The / is a simple but important distinction.

With that out of the way I went on to put things together bit by bit. At about 30 minutes in, I had to restart all over again because my architecture was messy and I had enough. The GitHub repo was deleted. I forked a fresh one, cloned it onto my system, and began over.

Fork, then clone

On GitHub’s website you can fork a repository. This makes a copy of the repo from the original owner’s account to yours. Great.

But the repo remains in the cloud, accessible only through your GitHub account. This is when git clone [url] comes in. Enter that into the command line with the URL on your GitHub account ending with a ‘.git’ format and your machine will download everything in the repo from the cloud, and establish a link between that repo (in the cloud) and the folder (in your machine).

Once that connection is made, it’s permanently binding. The only way I know to destroy the link is to manually key into the command line rm -rf .git when in the correct working directory that needs to be unlinked.

Confusing relative paths

I ran into a problem while trying to set the ‘background-image’ of a ‘div’ in CSS today that I think gave me a new wrinkle on the forehead. It has to do with folders inside a project.

finder screenshot

‘index.html’ is on the main directory, while ‘css’ and ‘img’ are their own subdirectories. That is intuitive enough. The problem’s root lies in the fact that it is convention to work on HTML and CSS as two separate files, and to store the HTML file in the main directory while the CSS file is stored in a subdirectory.

When writing code, I typically have two panes opened side by side – one for HTML, the other for CSS. To insert a background image for a particular ‘div’, I had to write this in the CSS file:

If only ‘path/to/image’ was so straightforward.

The actual relative path to the image—relative meaning relative to the path of ‘style.css’, not ‘index.html’—is “../img/bgtile.png”. For over half an hour I used “img/bgtile.png” and frowned as no background image ever loaded, no matter how hard I tried. If I was writing that line of code in the HTML file, it would have worked; I had completely forgotten, switching from one pane to the other incessantly, that I was not writing that in the HTML but the CSS file.

Good news is, mistakes like this will only happen once. Go through it once and you’ll never commit it again.

Like muscles

That brings me to my final point. Learning to code, I now realise, is like working out in the gym.

The aspiring programmer puts herself through strain each day just as a bodybuilder does with weights. At the end of the day, their muscles (be it in the brain, body, or fingers) are so worn out they have micro-fissures. In response, the body repairs the cracks by filling them up with protein, or in the case of the programmer, new neural patterns.

Repeat this enough days, and you’ll have an effective programmer!

I’m glad that on day 2, I’m already feeling my mind stretch.

Day 1 at General Assembly Singapore Web Development course

classroom at general assembly singapore
What our classroom looks like from the inside.

Michelangelo said this of marble: inside every block lies a sculpture to be discovered. All it needs is for its edges to be carved off.

I like to think that I’m my own sculptor, trimming the excess to make the whole coherent, compact and beautiful. Alas, I can’t be my own sculptor (who would be left inside?). Learning is a partnership, between marble and sculptor, student and teacher.

Yesterday I officially put one foot into the jungle of computer programming. Then I put the next foot in front of that, and then proceeded that way until the point of entry became nothing but a small dot on the horizon.

So far, I love it. Class was a little slow for me, so I spoke to one of our teaching assistants about it and got assured that things will pick up by next week. Meanwhile I was getting to know personally my instructor and TAs—programmers!—and that was fulfilling. Never had I known programmers on this level. I was finally speaking to them at a technical level. And now we’re friends in profession.

Having it easy

There’s something to be said about getting tips before having to live with the pain it purports to relief.

An example: setting up Terminal to open new sessions starting from the current working directory (instead of home) by default. Having before used the Terminal on Codecademy exercises as well as for using ‘SSH’ protocol with my Raspberry Pi single-board computer, I felt the inconvenience of always starting from the home directory – but never thought to solve the problem. But when Steve, our instructor, told us it’s useful to change the default, I did and enjoyed the new convenience. My classmates who haven’t used Terminal before might not be able to appreciate the change as much.

Jumping from self-learning through online courses (like Free Code Camp and Codecademy) to an in-person instructional course means, in many respects, having it easy. There’s no longer a need to be constantly on your toes, eyes wide and ears propped up to read and interpret every moment and asking yourself, “Is there a better way to do this?”, or “Am I missing something here?” Instead, instructors volunteer that information to you in good spirit as their new friend in the industry.

Having it easy is a privilege. As with any, it is easily taken for granted. What’s important for learners to remember is how much experience it took for tips to accumulate in our instructors’ minds, and to always wonder, “What is it like to not know this hack, technique, solution?” I find that asking “How did you arrive at this?” and “What else did you try?” helps to illuminate the pre-problem-solved history and helps me appreciate the real value of a little tip.

Oh, speaking of tips, I also ditched Sublime Text editor to Atom yesterday because a TA vouched for it. While I don’t believe that any good editor is measurably superior to another, I trust the instructor, so I’m going for it. Best to remind yourself that the editor is just a tool. You should still be able to write a programme with TextEdit and the internet.

DNS for real-life addresses

Why is there no domain name service (DNS) system for real-life addresses? Steve reckons it would be a superior way of recording every person’s home address.

What is DNS? It’s a simple system that resolves a textual domain name, like “”, into an IP (internet protocol) address. What few people outside the internet industry know about IP is that every website online is actually found via an IP address, not domain name, in the back-end. Try keying in ‘’ into Chrome – it should load!

If every address in reality has a permanent DNS name, say “Nick.Ang123” then whenever we move homes the only thing we’d need to do is go to the DNS registrar and update our IP address in the back-end. All mail marked for “Nick.Ang123” will still go through to the correct address!

Sounds like a better system to me. Probably just a matter of time before a city government adopts this and gets the ball rolling.

I still haven’t found the answer to this question though: who runs the DNS for the internet?

Mac viruses

A classmate told me that she had changed from a PC to Mac because it didn’t have any viruses. Is that true or just a well-managed problem on a Mac? If it’s truly virus-free, I’m curious to find out, which aspect of the OS X architecture makes it scum-free?

Technical bits

  • If you create a file/directory when logged in as root, it remains a root-created file and will always require root permission to edit!
  • IP addresses have 4 blocks of 3-digit numbers, from 0-255. 255 ** 4 = 4 billion. That’s not enough. That’s why we moved to IPv6!
  • Who runs DNS?!