Usually, every product story starts with a pain, a problem that needs to be solved. A problem that bothers you, annoys you, you face it frequently and probably you are not alone with it.
This case was not different either.
A few months ago we started to use a new HR system that has a lot of advantages compared to the old one. But it had disadvantages too… Missing functionality, missing information… or the information is there, but hard to get it out from the system.
That’s when the idea of Pandoo (the holiday planner) was born.
The new tool did lack some features that we got used to.
A nice(r) and clean(er) way to see all of your holidays, your team’s holidays (and type of those holidays), and book them in a bunch.
Disclaimer: Maybe some of these problems are manageable with admin configurations or with educating the users.. but usually, when people switch tools they just expect that “it works” and they have all the things they had previously plus nice extras.
The goal of this article is not to blame the tool, it is about the solution and the key learnings.
I wanted to bring back the functionalities from the old tool. I wanted to see my holidays as I was used to, I wanted to book my holidays as I used to. And I was not alone with this.
The Requirements
The Choice
Why?
Flutter is a cross-platform tool made by Google, that helps you build native mobile apps from a single codebase.
(Edit (19/09/2020): This has been changed a bit as you will see it later. )
I had some experiences already
I have built Edengreen, a tool that helps you check your available meal vouchers.
It is a really basic app, but it taught me the basics of how Flutter works. At this time Flutter was still in beta.
One of my other projects was CoronaVirus Alert, a tool that monitors the infections country by country and sends you push notifications.
In this project, I have played with Firebase, serverless functions, and custom scripts here and there. I have learned that there is a big pool of third-party libraries for Flutter and the community is growing rapidly too.
Web support
I have never tried, but apparently, there was rudimentary Web support too.
The challenge
My previous projects helped me to understand the basics but I wanted to achieve more and the Web support was sounded interesting too.
I needed a giant scrollable table view where horizontally I can show the days of the year and vertically all of my colleagues and their holidays.
This sounds easy, but in reality, it never is. Weird, annoying edge-cases when you are almost done, lack of Flutter knowledge from my side, unforeseen platform limitations, etc…
I wanted to see what is available already by the community, maybe there is something that is similar and it can fit my needs (with minimal tweaking). Luckily I have found the horizontal_data_table package, that provided 90% of what I have needed… I have forked the package and did some fine-tuning for my needs on the way.
Getting the data from the HR tool was pretty easy, they provide a nice REST API to interact with the back-end.
When you connect the dots you have to be cautious. You need to know what you expect from your tool, how it is going to work. How does it get the data? Do we need to store the data locally? Do we need an extra server-side logic too? Do we plan to use any exotic UI elements?
These are important questions, because when you pick a library/package in Flutter and e.g. if it works on Android it does not mean automatically that it works on iOS too… or even on the Web. You need to pick libraries that rely on the default native support and no additional native third-party libraries. (Or the reliance on those libraries needs to be complete on every side.)
For example, if you would like to use Firebase services in your app, you need to check which platforms are supported. If your target is not, probably you will face a runtime crash when Flutter tries to access the non-existent APIs.
When you search for a Flutter package in the official Dart/Flutter package repository, you can also see which platforms are supported.
Based on past experiences in the MVP I did not choose any special external library (except the horizontal_data_table) because I wanted to limit the compatibility issues between iOS, Android, and Web.
After I was done with the minimal version, I tested the implementation on Android and iOS.
It worked and looked nice! (Sure, it had some performance issues here and there while scrolling through the holidays of the whole company… but on a limited dataset it was good.)
So now we have two apps ready to use!
Let’s see how it works on the Web.
Of course, it crashed in a few places 😀. But nothing serious that a good old “if-else” could not solve. I have still used some APIs that were not available on the Web, so I needed to use
kIsWeb
constant to differ the logic between Web and native mobile.It also had some UI quirks due to unsupported/buggy UI elements (with gradients), but it was good enough for the current phase.
We have the third app too, and you could say “Ok, you are done, you have it all, Web runs on all platforms”.
But wait, there is more!
I really like Meetups. I can meet with like-minded people, listen to good and interesting presentations, and sometimes I give a talk too 😊.
There was a promising Meetup from GDG Brussels on Flutter topic. Based on the presentation summary, it intended to be a basic Flutter intro and the experiences of the author.
So it could be nothing interesting for me, I am kinda done with the basics… but I always like to repeat similar things, because maybe I can discover a new bit of information that can change my perspective and start me thinking. For the same reason, I read/listen to books on similar topics too… even the 95% is the same as a previous book, the remaining 5% is worth the time.
Luckily this case was not different either.
The presenter walked through their app development challenges and how quickly they have re-implemented the apps from scratch in Flutter.
Then he showed something interesting. His app was in a weird-looking window. It looked like a browser or a bezel-less iOS simulator. Apparently, it was his application compiled into a native MacOS app. It turned out that Flutter added support for Desktop platforms. Obviously, this was even in an earlier stage than the Web support, but it is worth a try.
The next day I tried it, it worked! I had Pandoo as a native MacOS app. Meanwhile, I have discovered that there is also really basic support for Linux and Windows… After the initial setup of the environments in VirtualBox, I could compile Pandoo as a native Windows and Linux app too! 🎉
Sure, there were some extra limitations on Windows and Linux, I had to do some extra “if-else” conditions. E.g. there was no persistent storage API available on these platforms, so I could not save any data to the disk.
(Edit (19/09/2020): Later I did polyfill these missing features by using the default Dart file reading and writing APIs.)
Extra three apps are done. Sounds good, doesn’t it?
We can argue on this if it counts as the seventh app or not. But it was such a nice surprise to me, so please allow me to count it as +1.
While I was testing Pandoo in the Chrome Browser on my phone, I got a popup that asked me if I would like to add Pandoo to my home screen. Sure, why not. But this icon on my home screen looked different from another page link. And… it also appeared between my apps in the Launcher. What?
It turned out that the Web apps built by Flutter are PWA applications too. So even if the device is offline, you can open and use the web apps. Or, you could… if a webpage is made for that. In my case I don’t cache any data from the HR tool, I fetch all the data from the API every time. That means when Pandoo is loaded inside the browser and you try to use it without an Internet connection, it shows an API error (just like all the other versions of the app). I could save the last fetched data locally and load it immediately at app start (while the new is loading)… but for now, it is ok as it is.
I think Flutter is a strong candidate in the app development era. Not only for mobile but in general.
I did not write a single line of code to have a Mac OSX app. Although I have some experiences with Mac OSX apps (Mike) so I would have an idea where to start, it is not a copy/paste from an iOS app, you need to put some work there. Hopefully Mac Catalyst will help with this in the future.
Write an app for Windows and Linux? I would not even think about it.
The additional Web support is really nice, and it can be really useful. For example, if you have a Revolut and TransferWise account you probably noticed that the mobile apps are very similar to each other, and they also provide a Web version too with a limited feature set. I don’t know what technologies they use, but (if not Flutter already) I can imagine in the future these kinds of services will consider Flutter for their apps.
In this timeframe, I was able to develop the most important part of the app, the giant table view with all the data in it, the holiday balance view, and the way of requesting holidays one by one.
I don’t count the extra menus, extra functionalities, going to the Meetup 😀.
For the additional basic Desktop support, I don’t count any minute. Basically, there was no code change done, except when I saw a crash I did put an “if-else” around the problematic part and it was “fixed”. Also, the later polyfill changes were not taken into account.
Key learnings
In general:
About Flutter:
Did you enjoy my story? There is more in the pipeline… 😉
Do you want to know more insights? Would you like to discuss the used techniques, or would you like to see some part of the code? Then consider becoming a monthly supporter on Patreon via my Tweaked.Tech initiative.
Why?
I really appreciate a one time support too, you can do it via Buy Me A Coffee.
Thanks for reading my story, I am grateful that you were here until the end.
Previously published at https://danieldallos.com/posts/2020/07/how-i-built-6-1-apps-in-one-day/