Weather App with “mvc_pattern”

Greg Perry
Follow Flutter
Published in
8 min readFeb 18, 2019

using Bloc by Example

MVC
Other Stories by Greg Perry

On February 9th, 2019, Felix Angelov wrote a wonderful article on the Flutter package, flutter_bloc, demonstrating how to manage multiple ‘Business Logic Components’ (or BLoC’s) to implement dynamic theming, pull-to-refresh, and much more. This package helps implement the BLoC pattern, and the article demonstrates this with a simple Weather app.

The article is available here:

Weather App with “flutter_bloc”

Now again, Felix’s focus in the article was the managing of more than one BLoC in an application. Therefore, this Weather app has one BLoC responsible for the fetching of weather information, another for supplying the ‘theme’ or color scheme to match a particular forecast, and finally, another BLoC is involved in the app’s settings: toggling the temperature between Fahrenheit and Celsius. As it happens, such demands don’t exactly take full advantage of what Bloc has to offer.

However, it did allow for an alternate approach. This implementation of Bloc extensively uses the Streaming capability of Fluter. However, since the app involved extensive user-interaction with the fetching of data, dynamic theming, pull-to-refresh, etc. all initiated solely by the user, streaming is not necessarily a vital trait for such an app. It could readily be done without streaming. For example, such an app could be done with the Flutter package, mvc_pattern.

This is no reflection on BloC. Far from it. With one change to the app’s specs. to require ‘real-time’ weather forecasts, for example, I would suggest you’re halfway there if you already had it implemented with Bloc. An app requiring the intermittent if not constant streaming of variant data is right up in Bloc’s wheelhouse. However, with the app example’s current specifications, and with Felix’s permission, I wrote the very same Weather app, blatantly using much of the existing code from his example app to convey another approach.

You see, some developers today may not have personal experience with MVC. Not directly, anyway. After all, it is a 40-year old design pattern. However, they likely have indirectly been exposed to MVC since many of today’s design patterns are its descendants. This article is an attempt to further explain MVC using a Bloc example as a reference. The implementations may vary, but the general concept they follow is the same.

Let’s begin.

Some Assumptions Right off the Hop

Right off the hop, I’ll assume the reader is somewhat familiar with BloC and with MVC. However, since my target audience is developers with little or no experience with MVC, I will only suggest, right here and now, to first read the article explaining my interpretation of MVC as it was implemented in the Flutter package, mvc_pattern:

Flutter + MVC at Last!

Hey! You’re back! Great.

I Like Screenshots. Click For Gists.

As always, I prefer using screenshots over gists to show concepts rather than just showing code in my articles. I find them easier to work with. However, you can click/tap on them to get at the code in a gist or in Github if you must. Ironically, it’s better to read this article about mobile development on your computer than on your phone. Besides, we program on our computers; not on our phones. For now.

The Same View

Like the Bloc implementation used by the Flutter package, Flutter_bloc, the build() function of State Objects serve like the ‘View’ aspect of MVC in the Flutter package, mvc_pattern. Such build() functions are then peppered with one or more instances of a ‘ Business Logic Component’ (be it a BLoC or a Controller). It is they that then supply the ‘data’ to be displayed in the build() function.

Looking at the ‘main view’ or the home page for both app versions (It’s a pair of StatefulWidgets; one named WeatherHome and the other named Weather, respectively.), You can see both Felix and I decided to instantiate our respective ‘Business Logic Component’ in the StateWidgets’ initState() functions.

class WeatherHome in weather_home.dart | class Weather in weather.dart

Side By Side

Looking further down the respective StatefulWidgets, both build() functions are, indeed, dotted with instances of their ‘Business Logic Components’ responsible for responding to all the user-interaction and controlling what is then displayed as a result. Looking at both screenshots side by side, you’ll see their implementations may differ, but the results are the same. Note, I will not ‘get into the details’ describing the respective implementations of these build() functions — they’re beyond the scope of this particular article.

build() in weather_home.dart | build() in weather_home.dart |

Back To Our Theme

Further, both versions utilize the ‘theme’ property of the MaterialApp class. That class is instantiated back in the very first Widget created for both apps respectively. In the Bloc one, it’s called App. In the MVC one, it’s called WeatherApp. But what’s in a name? In both versions, we then move on to call on their respective ‘home’ widgets — class WeatherHome and class Weather respectively. Those you’ve already had seen above.

Business Logic Component Number Two!

It is here, in these ‘app’ classes, where you’re introduced to the second BLoC and Controller used in each app. Both are responsible for providing the ‘Theme’ to accompany the next weather forecast retrieved from the first pair introduced above — when a location is selected in the app. Highlighted with little red arrows, you see below where each is injected into the Flutter’s own native framework, giving each access to their respective State objects. The second set of little red arrows shows where the property, theme, is assigned its respective values.

Set Your Temperature

The third and last BLoC in Felix’s example involves determining whether temperatures are to be displayed either in Fahrenheit or in Celsius. Below you can see each version retrieving and applying the current setting. The default setting in this simple Weather app was Celsius.

build() in combined_weather_temperature.dart | build() in weather_temperature.dart

There are No Settings To Set

Note, at the time I downloaded the example code from Github the App’s Settings weren’t implemented any more than before. With that, I took the liberty to whip up a simple drawer displaying a toggle switch to move between Celsius and Fahrenheit.

Settings Option

Set Your Temp

Supplying such a menu allowed me to implement that third and final BLoC in the Bloc version as well as its Controller counterpart in the MVC version. And so, below are the two versions used to present the user with a toggle switch if and when they want to change the temperature reading from Celsius to Fahrenheit and back. Again, highlighted with little red arrows are where the current unit settings are retrieved in both versions, where the unit is toggled, and where the app screen is ‘refreshed’ to display the new temperature reading.

SettingsDrawer() in weather_home.dart | SettingsDrawer() in weather.dart
class Switcher in settings_drawer.dart

Note, the Switcher class I just made myself — to pass on two specific values to the Drawer.

The Callback

Back to the second BLoC and Controller used in each app — again, the ones supplying the theme for each new forecast. Both actually call back to the State object they were originally associated with. Specifically, both call their State object’s setState() function. Let’s see where they do that.

Different themes for different forecasts.

In The Beginning

When the app starts, the first StatefulWidget is passed to the runApp() function and a BLoC and Controller is instantiated and ‘associated’ with a State object. They’re the first ones instantiated, but were the second ones introduced in this article: The ‘Theme’ BLoC and ‘Theme’ Controller.

main() in main.dart | main() in main.dart

Below are those StatefulWidgets passed to the runApp() function. Again, you can see where the respective BLoC and Controller are ‘linked with’ their State objects. With the Bloc version, the class object, BlocBuilder, is itself a StatefulWidget. It’s this StatefulWidget’s State object that the BLoC class, ThemeBloc, is associated with. The MVC version simply supplies its Controller to the very first State object encountered, _WeatherAppState.

class App in app.dart | class WeatherApp in weather.app

Set The State

In both versions, you can see in the first pair of screenshots below where their respective ‘weatherChanged’ events are initiated. As a result, you can see in the second set of screenshots below, where the function, setState(), is called inside each respective section of boilerplate code. In other words, both approaches have the mechanism in place for their respective ‘business logic components’ to call their associated State objects to rebuild their Widget trees.

build() in weather_home.dart | _subscribe() in bloc_builder.dart | build() in weather.dart | refresh() in mvc_pattern.dart

Code By Example

This Github repository will have the Weather App implemented with this alternative approach. In fact, as you may already have realized, Felix’s Weather App example code is in there as well — the code I originally retrieved back on Monday, February 11th, 2019 anyway. Going to the file, main.dart, you could alternate between the two approaches if you wish.

main.dart on Github

It’s Not Just Code…It’ An Idea

This article does provide an alternative approach, but the ideas behind each are the same. Bloc would work just the same, if not better…particularly with the ‘real-time’ feature. The main message here is that, from reading this article, you can see Bloc follows the MVC design pattern with the explicit effort to separate the business logic from the presentation layer and from the data layer. It’s just that, as in life, there never is just one answer, never just one approach. There are options out there. Developers should always be aware of other options.

Cheers.

→ Other Stories by Greg Perry

DECODE Flutter on YouTube

--

--