Monday, March 23, 2020

Vue.js and dialogs

Let's think for a moment about modal dialogs. What is their usage pattern? What are they for, I mean conceptually...

Dialog unveiled

When we create a dialog it is usually to gather some feedback from the user. It might be either a simple Yes / No or some form that the user needs to fill in and return that input after some form of interaction with that dialog.

Unfortunately there is no direct support for this kinds of interactions in Vue.js (nor in any other reactive framework, to be honest). This means that we need to resort to stuff like this:

data() {
  return {
    isConfirmationDialogVisible: false
  }
},
methods: {
  showConfirmationDialog() {
    this.isConfirmationDialogVisible = true
  },
  hideConfirmationDialog() {
    this.isConfirmationDialogVisible = false
  },
  handleConfirm() {
    this.hideConfirmationDialog()
    // the dialog ended with "OK" - perform some action
  },
  handleCancel() {
    this.hideConfirmationDialog()
    // the dialog ended with "Cancel" - do nothing
  }
}

The reason why we're doing all the state mutation nonsense in every place where we want to use a dialog is that the general approach in framework such as Vue.js is to base everything on state and we're completely ignoring the imperative nature of some of the processes. What is even more disturbing is that quite frankly the isConfirmationDialogVisible doesn't really belong with the place of use of the dialog. It should be an internal implementation detail of the dialog itself. But since we don't have implicit support for imperative programming with Vue.js it is sort of necessary to resort to stuff like that. But is it?

API is not just props and events

You might be tempted to think about the API of a component in terms of props that component accepts and events it emits. And even though they form a very important way of communication between parent and childs it is only 2/3rd of the story. Each method you define in the methods block is essentially part of the API of a component.

Suppose we have a dialog component that has the following two methods:

methods: {
  open() { ... },
  close() { ... }
}

Now if we use that dialog component somewhere it is quite easy to call those methods:

<template>
  <MyDialog ref="dialog" />
</template>

<script>
export default {
  mounted() {
    this.$refs.dialog.open()
  },
  beforeDestroy() {
    this.$refs.dialog.close()
  }
}
</script>

This means that we can imperatively steer when the dialog is open and when it closes. This way the state of visibility of that dialog is stored with that dialog and not in every place that uses that dialog which improves the usability quite a bit.

Promises, promises

Knowing that we can actually call methods on components let's move on to the concepts of modal dialogs.

Modal dialogs are dialogs that limit the possibility of user interaction to their content and usually finish with some result of that interaction. A good example is a popup that asks a question to which a user can say Yes or No or prompts the user to enter some data in which case there are usually two outcomes too: either the user entered the required information and approved his/her choice by pressing OK or resigns from proceeding, usually with the user of a Cancel button. It all bears a lot of resemblance to the alert() and confirm(), doesn't it?

The way it is usually handled in other frameworks (the Windows API, GTK just to name a few) is that the call to the framework method is blocking and once the user interaction is done it returns some result. In the browser a blocking code like that would result in everything going sideways. However, and this is where JavaScript really shines, there is a built-in concept of values that will be delivered later in time. This is the concept of Promises.

What if our dialog would expose a function like that:

methods: {
  async show() {
    return new Promise(resolve => {
      this.resolve = resolve
      this.show = true
    })
  },
  onOkButtonClick() {
    this.show = false
    this.resolve && this.resolve('ok')
  },
  onCancelButtonClick() {
    this.show = false
    this.resolve && this.resolve('cancel')
  },
},
data() {
  return {
    show: false,
    resolve: null
  }
}

Now that we have this we can use it in the code of a component that needs this kinds of interaction in a very nice way:

methods: {
  save() {
    const confirmation = await this.$refs.dialog.show()
    if (confirmation === 'ok') {
      // do something, the user is OK with it :)
    }
  }
}

The most important part of that approach is that you're not multiplying state that doesn't need to be multiplied and as a bonus your code expresses the intent: show a modal and react to the result of its interaction with the user

Have fun!

Wednesday, March 18, 2020

How to be successful when coding from home?

These are extraordinary circumstances for many organizations. The corona virus has forced a lot of people to stay home. This means that many people have found themselves in a situation they have never been before and might not feel very comfortable just being alone. In this post I'll try to share my tips for working remotely that I have gathered for over 7 years and being quite successful in it. Quite frankly I would never go back to the way things were before...

The bottom line

If you're like me and you don't feel like reading long posts here are the highlights:

  • Control is good - trust is better and pays off in spades! It is especially difficult for managers when they have no oversight over their workers but it is absolutely necessary to hold your horses and let the situation settle. This is where many managers will fail and only the best ones will prevail. That being said it is equally hard on employees to trust themselves.
  • If you're an employer you must believe in your people. They will do a good job even if it will take them time to adjust and get comfortable in the new situation. Judge the effects of work - not the workers - and remember that chemistry doesn't happen over night. Manage your expectations!
  • If you're an employee know that working from home doesn't mean you're off work. It just means that you have a really small office. It needs to be properly equipped and comfortable. Keep up the good work and you will prevail
  • Communication is key! Learn to use the tools at your disposal. Things like Skype, Hangouts, Zoom, Slack, Teams and Discord are there for you to take full advantage of what they provide. Make sure you have more than one tool at your disposal.
  • Limit the necessary communication. It is the key to not getting distracted. There is no such thing as an urgent email. And it also means you need to have a discussion about it with your wife and kids. Be fair to your family!
  • If you like working in pair use it to keep connected with your peers. Tools like VS Code combined with a voice call help you do that!
  • Make sure you have more than one option to connect to the Internet. LANs do break and having a backup LTE connection will let you concentrate on work and it will put yours and your manager's mind at ease :)

And one last thing...

The thing I found most difficult is to accept yourself. There's nothing in the whole wide world that's worse than judging yourself over and over again to the point where you are so down you can't take anymore. There are times when we're overly productive and times when we suck, big time. No matter how you want to slice it the sine wave is the most perfect shape in the world. It's the rule all living things live by, no matter if they like it or not. Accepting it will help you understand where you are, where you are coming from and where you're headed.

Have fun!!!

If you made it here and want to learn more about my experience with working from home - read on :)

The circumstances

My adventure with working from home begun some 14 years ago when I joined Sabre inc. It was the first company that employed proper VPN technology and gave us all laptops to work on. Since many teams were dispersed throughout different continents it was obvious that from time to time you would work in crazy hours. For example we have had regular team meetings every Thursday at 8pm CET. Staying at work for so long, although possible, was in fact not very practical (not to mention my wife was not very happy about it).

On top of that there were times when I needed to work directly with a guy that lived on Hawaii. That's 12h difference from CET! To put it in perspective if some of you end your day at 5pm it was 5am (yes! the middle of the night!) for Walker. Walker was a very important person (a VIP you might say) because he was the original author of the software we were working on. So he has had all the intimate knowledge of the system and was the best person to learn from. Frankly I wouldn't like to be in his shoes getting up 4am just to have a call with some guys across the globe :) And did I mention I am not really a morning person?...

The solution

And so I came to the conclusion that it would make sense for me to start working in a timezone that's a bit of both: 2pm to 10pm. This would mean I would have plenty of overlap with Walker and the rest of the team based in the US yet enough time to take care of my daily business. The downside, though, was that there was nobody in the office after like 6pm and staying alone in a huge office wasn't my idea of fun. So I worked remotely for half a year. There were no papers to be signed, no permissions to be given - just my personal decision to have more time with the guys overseas.

The first few days it felt really strange. I was organizing my home office for a few hours, reorganizing my desk every now and then to fit the new situation, then doing a bit of project work, having lots of time with the rest of the team in the States and in the evening watching a movie with my wife after work. The adjustment period went on for about a week and after that it felt like I was doing it forever.

Now that I think about it in fact I was doing it forever - just didn't realize it! I am a self learner. I didn't finish my study at the university, I wasn't particularly good in high school and even in ground school things were not looking very up for me. All because I preferred spending time coding. Yes, I started coding at the age of 12 and I knew I wanted to be a programmer when I was 6 years old :)... Quite frankly I don't know how I managed to meet that wonderful girl that I spent over 23 years with :) I think I just got lucky!

Communication

I am an introvert. My wife would say that's not really true but I know how I feel inside. It isn't a bad thing - it just means I can concentrate better when there's less people around me. Sure there are times when I am fed up with just my 4 walls and I am looking for some company. But that grows old very soon for me. Even though I can literally see the office from home with a naked eye I go there maybe once a month, often times even less. I found that it is way more productive if I can shut out everybody and just do coding. That led me to employing rules like checking emails only in the morning, keeping to the necessary minimum my interactions on Skype - you know what I mean.

How does that help you?

Tuesday, March 17, 2020

Using multiple ssh keys with Github (or any other host)

Imagine you're working on one machine with multiple clients. In that case each client might require you to have a separate account on Github. This means that you need to have separate SSH keys for those accounts too and that in turn means is a pain in the butt to have it working.

If you're on Linux (and probably MacOS too) there's hope for you! Follow those simple steps to get everything setup so that you won't even notice it is there!

Step 1: Add a host entry in ~/.ssh/config

Host client-github.com
     Hostname github.com
     User git
     IdentitiesOnly yes
     IdentityFile ~/.ssh/client_rsa

This allows you to connect to a host named client-github.com which will in fact connect to github.com but with a specific identity file (ssh key)

Step 2: Add the following 2 entries to your ~/.gitconfig

[url "ssh://git@client-github.com/client"]
        insteadOf = ssh://git@github.com/client

[url "ssh://git@client-github.com/client"]
        insteadOf = git@github.com:client

Using client-github.com is not really practical. There are instances (like linked npm modules from github.com) where you're not directly in control of the hostname. That's where the URL substitution in Git comes in handy. Whenever someone requests a URL from the client's namespace we substitute it with our custom address and everything's golden

Obviously if you substitute the client part of the custom hostname with the name of the client it will be easier for you to manage multiple such cases :) Just sayin'...

Have fun!

Friday, September 27, 2019

How to pass an interview?

This is sort of a generic post that I feel might help one or two people when they go for an interview. If you find it helpful throw me a comment. If you find it stupid and you feel that I am not right - say so as well. Criticism is WELCOMED!!!

The stage

The stage is simple: you are looking for a new job. For the sake of simplicity I will focus on a new job for a programmer.

The process

It does matter if you're applying for a job that is way above your current experience or if you're applying as an expert in a field  your client requires. In the first case it is extremely easy to pass: all you need to do is be open, make sure you outline what you don't know and what you're keen on learning, what you expect to gain (besides money!) from your new position and chances are if the employer is smart enough (and you engaged enough) that things will play out just fine.

The other situation is a bit different. You have to know what you're selling if you wish to sell it to someone. A good example (and a very good exercise before going to an interview) is to present your topic to an audience on a conference. So let's assume you apply for a position as an architect of some sort. Before you do the actual interview apply for a presentation at your local interest group (a meetup, conference - whatever!) and do the presentation. What's nice about it is you'll get immediate feedback from the audience. And remember: no feedback is also some feedback! It just means you have not been good enough to spark interest in your audience. And I don't mean Q and A session right after your presentation. If there are people hunting you after you're packed and ready to leave asking questions - you did a good job!

The reason I am bringing public presentations up here is because those are equally stressful as an interview and touch on the same kind of topics that you will encounter during an interview. Pretty much the same stuff. Imagine, if you will, you're presenting in front of 100 people (not uncommon even on local meetups). And all of the sudden someone asks you a question you know absolutely nothing about. How would you react? How would you react in a similar situation during an interview?

Epilogue...

This far I have I have had countless interviews - only two of them were negative and I didn't even want the position I was applying for. From that I am gathering that you only pass interviews for positions you will actually find yourself useful. If you really really really want to work for Google - get interested in the stuff they do. If you want to work for Microsoft (although I find it hard to believe) get interested in what they do. Learn their ways and technology, learn about their requirements and prepare yourself for what will be asked. Don't be ashamed to say I don't know. It is way worse to lie you know stuff than to admit it.

Wednesday, March 6, 2019

Designing as small stable Core XY 3D printer

The journey so far

I have been completely swallowed by the idea of designing my own 3D printer. Just like that. From the day I have put together my Ender 3 that finally came in from Ali Express all I could think of was this project of creating the smallest working CoreXY 3D printer possible. I don't actually care about the possible print size (unless it is smaller that 1cm per 1cm per 1cm). What I do care about is making the 3D printer easy to put together and solid as fuck.

Currently I am at a point where the structure is in place (and it is a tweaked one I tell you), all the roles are also in place and what I fight for at this point is to make the mount for the roles stable enough to handle the Core XY load with 3D printed elements)

Stay tuned for more information on how this printer is being created :D

Sunday, November 25, 2018

Making an UV image setter for PCBs

This is going to be a quick one. I wanted to do one of these for a long time but somehow it eluded me for quite some time (too long if you ask me)

The problem

I need to make a PCB for a small circuit at home. Conveniently. After I'm done designing the circuit it usually is late and the sun doesn't shine no more. I want to be able to use the photoresist dry film (foil) and I want it to be fast!

The solution

I used to use a 500W halogen, then an energy-saving fluorescent lamp but all of those things were just cumbersome. Finally I have decided to make use of UV emitting diodes.

See the following picture of a ready-made product:

The device is powered by a 3 cell LiPo battery (I have a bunch of them for my flying toys). The time it takes to properly develop the foil is ABSOLUTELY SHORTEST FROM ALL THE LIGHT SOURCES I USED BEFORE!!!

The 500W halogen needed circa 30 minutes in the setup I used. The energy-saving light bulb needed 12.5 minutes. This little toy does the same and more in 90 seconds!!!

The making

Making such a toy is extremely simple. You just cut as many pieces to length as much space you have in the housing of your choosing (I used the Z23 housing where I have cut a full-size hole in one of the parts).

Next you cut a piece of paper that fits inside the housing. Once you do that take the pieces of strips and glue them on to the piece of paper in a similar way that you see on the picture above. The point here is to make the as evenly spaced as possible.

Then you solder them to form a strip (plus with plus, minus with minus). On one end you solder any kind of connector (I went for the small JST one because I have a lot of them). Then just make a hole on the side where the leads with the connector are coming out.

Finally place that paper with glued strips inside, apply power and enjoy!

Happy PCBing!

Friday, November 23, 2018

The Flame Wars - story of my life

Flame wars have been with us for God knows how long. Christianity vs all other religions, Islam vs everyone else, socialism vs capitalism, Atari vs Commodore, Amiga vs PC, Macintosh vs the World, Linux vs everyone else. Fighting for our believes seems to be at the core of our nature. We just can’t help thinking that what we think is best must be the best - because we deemed it to be the case.

Developers are a particular strain of oddities: Whatever technology we seem to work with at the time seems to be either the evil incarnated or the impersonation of God - depending on the current hype among our friends that we trust know better. Very seldom it is the case we grow big enough balls to actually go over the fence, dig into the dirt and figure out for ourselves if the grass on the other end is really so gray as we deem it to be.

It has been an eye opening experience every time I took a turn in my career when it came to the tools I worked with.

I started in the 7th heaven owning an Atari 800XE and 3 games I could barely hold still while loading a game from a tape storage. For that reason I started to learn what the keyboard and TV set has to offer beyond playing Mr Robot and Forth Apocalypse and I discovered that, in point of fact, Basic was a part of the package.

Soon after that I became a sworn 6502/C64 freak at the age of 14. I know. I betrayed. I was the outcast. But I was doing ora-dycpys going over side borders while playing ripped tunes and waving Dedal logos. And I did it all in machine language - not even assembly! All I have had was the Final Replay 2 cartridge but for reasons I cannot fathom it was the best thing that ever happened for me. I was able to see the results of my work upon issuing a single sys command. And it looked great!

At that time Amiga was “the better game machine for me”. I mean, with all due respect, I still think that the playability of Giana Sisters, the Mario clone for Commodore computers, was way better on C64 than it was on any platform (even XBox!). Having said that I was kind of socially pressed into wanting the A500 with 512Kb of Slow RAM extension to be able to play Pinball Dreams and IK4+. But playing games was never my thing. After I saw how much Giana Sisters sucked by comparison I started looking for things to do with my shiny new computer. Pascal was there, but the animation example I saw was visually so bad that I couldn’t stand watching it. The C example didn’t even compile so I thought it was a waste of time to get interested in it. But the good old low level language, Motorola 68k assembler, was quite a nice fit for me after having a few years of experience in programming registers on its older uncle. Man, those plasma screens I loved so much! I was staring at it for hours! I was finally home!!!

At that time I remember reading a quite far reaching article about code quality. A couple of demo scene Gods discussed if it makes sense to write good quality code or if it is more important to just code it in the fastest way possible, win the compo at a demo party and move on to the next one. A question I sure hope the industry has answered so far to everyone’s satisfaction.

Being bored writing sinus scrolls, 3D animations and plasmas I started looking into this promised land Amos was said to be. With its Amal animation language targeting Amiga’s coprocessors it was told to be even better than asm itself. I remember it being the first IDE having an integrated debugger, forward function declaration and (upon pressing F9) code folding. Man! I missed that for years afterwards!

Then one day everything changed. My beloved A1200 was (again, upon the pressure of friends) exchanged to a 486SX with 50MB hard-drive. It was running DOS, Norton Commander, it looked bad (compared to A1200’s workbench) and what I had no idea then it was the first computer running an OS that was not Unix-like. Apparently, for what seems to be forever, I have fallen into the Redmond dream that I was unable to wake up from.

I remember a few years after that trying to install RedHat Linux from a 23 floppy disks installation - and failing miserably. I thought that those “Linux” guys must be insane to be using something like that. I was a sworn DOS enthusiast! I discovered Windows 3.1 and the only thing it was good for was multitasking to run the BBS software and at the same time to be able to code in Turbo Pascal that I fell in love with in the meantime. Pascal wasn’t fast enough though to write intros/demos so me and my friend resorted to “db 66” asm instructions to speed up double buffering.

Not long after that I learned that programming isn’t really something lots of people do particularly well - me included. That was when I discovered The Almighty Internet. Suddenly the knowledge that I craved for so much for so long became within my reach. But it was so overwhelming!!! Just going through some examples that I found on swagger took me a lot of time. Those were the times when I first saw Qnix - a windowing system-enabled one floppy-disk, Unix-like, free to use real time operating system. So Unix did have some appeal after all, I thought. I went even deeper when I learned about the Linux Router Project - a one-floppy-disk Linux distribution that did IP routing and masquerading out of the box. I knew Linux was the one - but it was so different than Windows and Dos Navigator that I grew so accustomed to!! All the things were different. That was just a hassle I was not ready to go through.

Fast forward a few years and the Turbo Pascal I worked in became Delphi and my professional career was booming! I was moving to a different country, founding my second business - I was on the roll! To have everything in check instead of buying Windows XP I decided to try out this “SUSE Liunux” as it was promised to “just install and work” on my PC. Well, it did. But it was soooo different than Windows XP and… Delphi didn’t run there. I was still deep in the Redmond dream.

I don’t remember when it really happened but it must have been when I received the Ubuntu 7 something CD for free. It really delivered on the promise to be approachable enough for everyone - this time me included. But Delphi still didn’t run there. By accident that was the time I went to a seminar in Warsaw where the successor of Delphi 7 was announced and I realized that this is the end of what I was able to get out of the platform. So I started looking…

At that time I worked in a corporation that offered me an option to learn Java and .NET. C# looked like a natural choice (being coordinated by the creator of Delphi himself) but for reasons I cannot fathom till this day I decided to go with Java. The first years were a disaster! Nothing was like it should have been. Java developers spoke of things I had no idea even had names (like refactoring, unit testing, clean code, design patterns) although upon deeper investigation it looked like we spoke about those same things - just naming them differently.

I fell in love with Groovy and Maven (I know - I’m different that way). I use both of those tools till this day with great proficiency. I think that Maven was the best thing that ever happened to Java. It made it approachable for mere mortals and freed us from Ant hell. Groovy on the other hand was for me the Pascal equivalent on the JVM. It had the concept of properties that I missed so much ever since I left Delphi behind. But at the same time I unwillingly became independent of the environment I worked in. Linux, Windows, OSX - I didn’t care anymore. So I realized one of my long-lived dreams and switched fully to Ubuntu - the Linux platform for the rest of us :) It was a natural step because all production servers were running Linux so using SSH that was not (and still isn’t) present on Windows felt so natural. And so, Windows became “the OS I sometimes run”. I do remember the day when I installed Linux exclusively without dual-boot. It felt weird - but good.

Since then I moved from Java to frontend development. Something I thought I had some idea of but was proven sooooooo wrong. Learned that what you see is not really what you will get (as in I finally learned what the hell everyone else was talking about in relation to Internet Explorer 6). But I love every bit of it. It gives out of the box tooling that on other platforms you need to pay good money for. To some extent I am even happy I learned about frontend development through the Ember.js perspective. It was the worst thing after getting struck by Java Server Faces but it made me explore the domain to see if there’s something that can substitute this horrible piece of machinery. So I learned about React and fell in love with it, I also learned about Angular and how it makes development more like I was used to from my times in Java and ended falling completely in love with Vue.js.

Then I decided to move to a company that thinks very little of frontend development but is really big on Sitecore. If you don’t know what Sitecore is think Wordpress on .NET that you can pay for because you think it is better than X or Y. This meant for me taking a round trip to the .NET world and the C# language.

At each step after a few months of digging in I felt my passion for software development giving away field to understanding of capabilities. Every week/month/year I meet sworn enemies of technology X than can give me 5, 10 sometimes even 20 reasons for not using the other, legacy, frameworks, languages, platforms. The truth however is that everything has its reason for existence. Yes, even jQuery and goto. I just wish I learned that years ago. The only thing that really counts is writing code for other developers to read (regardless of the platform/language) and questioning the status quo if it makes your life harder.

So going from 6502, through M68k, Amos/Amal, Pascal, Delphi, Java, JS and the browser and now .NET and Sitecore I learned only one thing: developing software is easy. But doing it right is hard. And if you don’t use whatever means necessary to help you out then sinking in the pool of your own blood and excrements is as obvious as the fact that sun’s rising in the east. The rule for me now is to first learn for myself if a piece of tech is useful in a context - not “in general”. And as a rule it has its exception for me: JSF. Everything else I learned over the years made me a better programmer, person, husband and father.

Happy years!