Building a basic Flutter app with Dart & an API Call
In a world where there are almost more ways to build mobile apps than ever before, it can be a daunting task to decide which road to follow. Do you build it completely native, using Swift or Android Studio/Java, or do you choose from a variety of cross-platform frameworks like Ionic, Cordova, Flutter, React Native or some other framework?
In an attempt to broaden my horizon, I recently went ahead and tried a framework called Flutter. Flutter is Google’s entry in the world of mobile frameworks, which uses it’s own programming language called Dart.
In this article I will be showing you how to build a small Flutter app which does an API call and then shows those results to the user, and how to debug an application like this.
Prerequisites
In order to follow this guide you will to install Flutter. For the purposes of brevity, this guide will be based on developing on Linux, and writing & testing the app for an android device.
Start Building!
Start by creating a new Flutter project, using the vscode flutter command Flutter: New Project
. Enter the name of your application and continue. Flutter will now provide you with all the boilerplate you need to start writing your app.
If you have configured an Android Emulator in Android Studio and press F5, you can now build and run your app on the emulator.
Adding a widget
When looking at the default code, you will see that almost everything revolves around Widgets. Basically everything in the app you see is a Widget. From the small Text
widgets that only display a piece of text, to the large Scaffold
widgets which lay a large framework for building the app.
Now we will add our own widget to this demo app. Instead of the MyHomePage
widget used in the default demo app, we will write our own Homepage widget. Start by creating a new file under the /lib
folder, called home.dart
. This file will contain our custom HomePage widget.
In the home.dart
file, write the following code:
As you can see, we build the HomePage Widget as a StatefulWidget
, meaning we can later add some state to it (like the results of an API call). When building a Widget, the most important part is the build
method. This method will define what the widget will be, what will be its contents and how to display those.
Now, in our main dart file main.dart
, we need to make sure to use our own HomePage Widget instead of the one provided in the default demo app. Start by importing the new file, by placing the line import ‘home.dart’;
on top of the main.dart
file. Then, in the build
method, replace the MyHomePage(title: "")
widget under home
with HomePage()
.
Running the app should now show 2 lines of text, which say ‘Text1’ and ‘Text2’ respectively.
Using data from an API
In order to use data from the internet, we will add an API call which show the current weather condition in a given city, say Amsterdam. We will use the OpenWeather API because we can do some API calls for free there to retrieve the current weather. All you have to do there is signup and get an API key to use in your app.
If you have your API key, we can start writing our own API calls that the app can use. Begin by creating a new file, called api.dart
under the /lib
folder. In this file we will handle the logic of calling the API, and parsing the result so we can use it.
Then, add a dependency to the http
package, which is necessary to do API calls. Do this by adding the line http:^0.12.0+4
(or a newer version if it is available) to the pubspec.yml
file, under dependencies
. Vscode should automatically download the dependencies for you (if not, you should run flutter pub get
in your project folder).
In the api.dart
file, write the following code:
Then, in home.dart
, import the api.dart
file with import ‘api.dart’;
, and add some code to the HomePageState
class which will make sure we call this new getWeather
function and store its results in the state. Do this by adding a local variable in HomePageState
: Future<WeatherResponse> _weatherData;
. Then override the initState
method, so the widget knows what to do to initialize its state:
Now, when we start the app, the HomePage
widget will always call the weather api when it is being initialized.
Displaying the results
The response from the API call is now sitting inside a Future object. If you come from a Javascript background, this is comparable to Javascripts Promise. When first declared, the _weatherData
variable will not have any contents, but these are loaded asynchronously by the api call.
In order to display anything from this _weatherData
object, we need to wrap it inside a FutureBuilder
Widget. The FutureBuilder
widget takes a callback function as argument, which will be called when the provided Future
object has resolved:
Now, when the app starts, a small loader will appear to show the API call is still in progress. When the Api call finishes, the FutureBuilder
reacts by calling its callback function again. Now the snapshot (which is a snapshot of the weatherData at that moment), has data (which we know because the .hasData
property is true. We can also check for errors with .hasError
to do error handling.
Now, instead of showing a simple Text widget to indicate the loading has finished, let’s intead show the actual weather information.
In the FutureBuilder
callback, instead of returing a Text
widget if the call has succeeded, return a Card
widget with the weather info. The Card
widget will make sure the info looks a little bit nicer:
If you now run the app and everything works, you should see something like this:
If you need to take a look at all the codefiles, you can find all the code for this little project here.