How I contributed to a Flutter application without knowing Dart.

How I contributed to a Flutter application without knowing Dart.

Background

My friend, Adewunmi, is studying to become an app developer. He is learning to use Flutter. Naturally, I am excited. My friend + programming = more things to argue about. You know, stuff like ReactJS vs VueJS, Tabs vs Spaces and other interesting stuff. All in all, I am going to have fun. Earlier this week, he showed me a calculator application that he developed. It was a great demonstration of the concepts he had learnt. Of course, I asked him to add a twist to the application. A learning project can be more interesting with a twist. The twist was to add a button to reveal the scientific features of the calculator. Such a feature would allow him to think out of the box and do things by himself. The replies I got from him were very interesting.

He stated that he had to learn how to use "Stateful widgets" and didn't want to go too far ahead of the course that he is taking. To me, it's important to go on tangents when learning concepts in a course. You get more out of such content that way. If you're making a music player, try making a live internet radio station. If it is a text chat app, add a voice chatting feature. You'll hit obstacles and get better trying to overcome those. Like I said before, a twist makes a project more interesting. I challenged him to a bet. If I am able to add the scientific calculator feature in an hour despite never writing Dart before, he would have to do that too. He loved my energy and he took the challenge. A bet that I lost badly. Before I got started, the app looked like below.

Screenshot_1637437639.png

Setting up a Flutter Environment

It took me a long time to set up my laptop for Flutter development. I was trying to use the Android Studio CLI tools without installing Android Studio. I installed the SDK manager but the flutter doctor command kept on failing. It eventually worked out well after following this tutorial on setting up a Flutter environment on a Ubuntu Linux machine. It took the whole hour, I already lost my bet and had to go back on my resolve not to install Android Studio on my laptop. It is safe to say I won't use it for anything other than the android toolchain management. I would have loved having something similar to a GitHub codespaces setup for Flutter. I wouldn't have to install anything to get work started. If you haven't read my article on GitHub Codespaces, you should check it out.

flutter doctor.png

Finding the right file to edit.

I finally had my laptop set up for action. "Show me the code and let me deal with it", I was ready to pounce on that codebase. Unfortunately, I couldn't find the file. Funny right? I was lost inside the maze of the codebase. I came across multiple android and ios folders containing XML files. "What is going on today?" was all that came to my mind. I was tempted to create a new flutter application but time wasn't on my side. It was during my travel through the code and into the test folder That I saw the light. The light was in the form of VScode's wiggly yellow line in the test file. Pressing CTRL+ Click took me to the main file named main.dart. Yay. Here we go! Time to get to work. Then I started messing around with the code.

Peek 2021-11-20 22-18.gif

Modifying the Codebase.

To be frank, Flutter code was very confusing at first. I was lost for a moment. Whenever I get lost in a codebase, I do the most strange things. I checkout the dev or main branch and I mess with the code. Yes, you heard me right. I'll try changing strings to numbers and duplicating several code blocks. The compiler complained severally and after a few strategic "mess-ups", I was able to recognise the block of code responsible for the buttons. It was a Row function containing several buildButton widgets. When I see something that looks like the image shown below, of course, I'll change it and see if it reflects.

error.gif

I changed the first argument of the buildButton widget and I saw that it reflected both in appearance and function. The next thing was to check out the implementation of the buildButton.

buildButton.png I understood that the argument buttonText serves as both the displayed text and the parameter passed to the handler function buttonPressed. This was okay for a basic calculator but I needed a little more flexibility than that without breaking existing code. Googling how to add an optional argument in a dart function led to a medium article with which I added an optional argument displayText to the buildButton Widget. I then used a ternary operation to set the text displayed to buttonText of displayText defaults to null.

newBulidButton.png

Using the buildButton widget looks somewhat like this.

buildButton("cos(", 1, Colors.green, displayText: "cos"),

It worked out well and I was able to add buttons such as tangent, cosine and sine. These buttons need to be displayed as tan but input tan( into the calculator. I added extra rows and columns to the buttons. I also added an extra button to do the switching from the basic calculator to the complex calculator mode. The button wasn't functional and I had to do something about it. The calculator at this point looked like I wanted it to look.

IMG_20211118_125316.jpg

All this while, I was editing the existing Row widget. It meant my calculator was simply a scientific calculator by default. I went back to the GitHub repo that my friend shared with me and copied the previous Row widget. I wanted to rename it as a separate widget and return it based on the value of a variable that would be toggled by pressing the ext button. Flutter didn't agree with me. First things first. I created a global variable named status in the _SimpleCalculator Class and made it default to false. I then modified the buttonPressed handler function to toggle status if it receives ext as an argument. All it took was an else- if statement.

handler.png

To return a different Row widget based on the value of status, I tried using a ternary operation in the body widget. For reasons I don't know, it didn't work. I ended up using an if statement based on the value of status. After all, a ternary operation is a "hard-to-read" ifstatement. The code looks like shown below after everything. Notice that we initially had one Row widget in the code. Now, we return the needed Row widget based on if status is true or false. Pretty simple, huh?

rowrow.png

The code is not beautiful but it works. The Row on line 133 is the scientific Row(Keyboard) while the other is the basic Row(Keyboard). The result is as shown below.

Peek 2021-11-20 22-13.gif

Conclusion

Making this improvement to the application demonstrated several things. The first is that concepts are applicable across languages and frameworks. You don't have to know a 100% about something to implement it in code. While writing this piece of code, I spent the bulk of the time thinking about how I would write something that I already knew in Dart. My thoughts weren't in JavaScript or Typescript or Go but in terms of the concepts that I learnt growing up as a developer. After all, languages and frameworks are simply tools with which we birth the ideas and concepts that we have in our minds. This is a very important point to take away.

In addition, I tried as much as possible to follow the flow of the codebase while modifying it. It allowed me to copy and paste several codeblocks without worrying if they will work or not. While some won't work, I usually end up checking Google for why it didn't work and having that at the back of my mind moving forward. I didn't browse how to do an if statement in Dart while writing this code. I simply copied and pasted it from the same codebase. I'm sure my friend would have a tough time knowing which code is his and which is mine.

Finally, using Google is a great way to learn and overcome obstacles. You are not the first to encounter problems and it is very important to know how to search the internet for solutions to such problems. One can argue that being a "FullStackOverflow developer" is an important part of being a software developer. Hone your googling skills and you won't be afraid of breaking codes once in a while.

Thank you for following my adventure into the world of Dart and Flutter. I am by no means a Flutter developer as I can't boast of being able to write a Flutter application by myself without the help of Google. I had fun though. I hope my friend still goes ahead and implement the feature even though I lost the bet.