Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(flutter_weather): update tutorial #2519

Merged
merged 12 commits into from Jun 17, 2021

Conversation

jonathankao97
Copy link
Contributor

@jonathankao97 jonathankao97 commented Jun 7, 2021

Status

in development

Breaking Changes

no

Description

update flutter weather tutorial (closes #2357)

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Bug fix (non-breaking change which fixes an issue)
  • ❌ Breaking change (fix or feature that would cause existing functionality to change)
  • 🧹 Code refactor
  • ✅ Build configuration change
  • 📝 Documentation
  • 🗑️ Chore

|-- test/
```

Next, we will be use the same packages as in the `meta_weather_api` package. In addition, we will also use the `meta_weather_api` package which we just created. Update your `pubspec.yaml` to look like the following and run `flutter packages get`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, we will be use the same packages as in the `meta_weather_api` package. In addition, we will also use the `meta_weather_api` package which we just created. Update your `pubspec.yaml` to look like the following and run `flutter packages get`
Next, we will be use the same packages as in the `meta_weather_api` package. In addition, we will also use the `meta_weather_api` package which we just created. Update your `pubspec.yaml` to look like the following and run `flutter pub get`


?> **Note:** We are going to add some assets (icons for weather types) in our app, so we need to include the assets folder in the pubspec.yaml. Please go ahead and create an _assets_ folder in the root of the project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this note back in?


### Theme Cubits

Next, let's put together the HydratedCubit we will use to keep track of the theme of our app. The goal is to have the theme changed based on the current weather information.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, let's put together the HydratedCubit we will use to keep track of the theme of our app. The goal is to have the theme changed based on the current weather information.
Next, let's put together the HydratedCubit we will use to keep track of the theme of our app. The goal is to have the theme change based on the current weather information.

|-- theme_cubit.dart
```

We will expose an `updateTheme(Weather? weather)` method, which will update the theme cubit depending on the weather condition
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We will expose an `updateTheme(Weather? weather)` method, which will update the theme cubit depending on the weather condition
We will expose an `updateTheme(Weather? weather)` method, which will update the Theme Cubit depending on the weather condition

- If our weather states return correct `WeatherStatusX` values. [Here](https://github.com/felangel/bloc/blob/master/examples/flutter_weather/test/weather/cubit/weather_state_test.dart) is a completed test file
- If our HydratedCubits respond to events properly and is able to convert fromJson and toJson

In addition to using `Mocktail` for mocking and the standard testing library, it is also reccomended to use [bloc_test](https://pub.dev/packages/bloc_test) library. `bloc_test` allows us to easily prepare our blocs for testing, handle state changes, and check results.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In addition to using `Mocktail` for mocking and the standard testing library, it is also reccomended to use [bloc_test](https://pub.dev/packages/bloc_test) library. `bloc_test` allows us to easily prepare our blocs for testing, handle state changes, and check results.
In addition to using `Mocktail` for mocking and the standard testing library, it is also reccomended to use the [bloc_test](https://pub.dev/packages/bloc_test) library. `bloc_test` allows us to easily prepare our blocs for testing, handle state changes, and check results.


### Weather Page

With the core logic of our app put together, it's time to put together the UI! We will start with the weather page which uses `dependency injection` in order to provide cubits to widgets. This is accomplished using `BlocProvider` and `BlocConsumer`. These objects essentially inject our Cubits whenever widgets are (re)rendered.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
With the core logic of our app put together, it's time to put together the UI! We will start with the weather page which uses `dependency injection` in order to provide cubits to widgets. This is accomplished using `BlocProvider` and `BlocConsumer`. These objects essentially inject our Cubits whenever widgets are (re)rendered.
With the core logic of our app put together, it's time to put together the UI! We will start with the weather page which uses `dependency injection` in order to provide cubits to widgets. This is accomplished using `BlocProvider` and `BlocConsumer`. These objects inject our Cubits whenever widgets are (re)rendered.

}
```

This page depends on `SettingsPage, SearchPage` widgets, which we will create next
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This page depends on `SettingsPage, SearchPage` widgets, which we will create next
This page depends on `SettingsPage, SearchPage` widgets, which we will create next.


## Presentation Layer: Individual Weather Widgets

We will next create the UI for our app. Each individual widget corresponds to a particular state our Cubits can be in.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We will next create the UI for our app. Each individual widget corresponds to a particular state our Cubits can be in.
Now we will create the UI for our app. Each individual widget corresponds to a particular state that our Cubits can be in.


### WeatherPopulated

Next, lets create the UI for when a city has actually been queried for.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Next, lets create the UI for when a city has actually been queried for.
Next, let's create the UI for when we query a city.


## Presentation Layer: Views

Let's glue the rest of our app together!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Let's glue the rest of our app together!
Let's put the rest of our app together!


## Testing Our Widgets and Views

In order to feel comfortable about our testing coverage, we should also test the widgets and view pages we have created. Again, we also reccomend using the `bloc_test` library for this.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In order to feel comfortable about our testing coverage, we should also test the widgets and view pages we have created. Again, we also reccomend using the `bloc_test` library for this.
In order to feel confident about our testing coverage, we should also test the widgets and view pages we have created. Again, we recommend using the `bloc_test` library for this.


[Here](https://github.com/felangel/bloc/tree/master/examples/flutter_weather/test) is an example test suite which includes widget tests, cubit tests, and view tests.

## Putting it all together. Visually testing functionality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Putting it all together. Visually testing functionality
## Putting it all together!


[weather.dart](_snippets/flutter_weather_tutorial/settings_button.dart.md ':include')
The completed file, put together, looks like this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The completed file, put together, looks like this
Put together, the completed file should look like this:


### Unit Testing our Data Layer Models

First, let's unit test our data models, `location` and `weather`. We should focus on insuring that they can represent our data, translate from and to JSON form, and handle edge cases.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
First, let's unit test our data models, `location` and `weather`. We should focus on insuring that they can represent our data, translate from and to JSON form, and handle edge cases.
First, let's unit test our data models, `location` and `weather`. We should focus on ensuring that they can represent our data, translate from and to JSON, and handle edge cases.


First, let's unit test our data models, `location` and `weather`. We should focus on insuring that they can represent our data, translate from and to JSON form, and handle edge cases.

First, add the Dart testing library to our `pubspec.yaml` and run `flutter pub get`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
First, add the Dart testing library to our `pubspec.yaml` and run `flutter pub get`.
Add the Dart testing library to our `pubspec.yaml` and run `flutter pub get`.


## Repository Layer

The goal of our repository layer is to create a wrapper for our data layer, and facilitate communication with the Bloc layer. In doing this, the rest of our code base depends only on functions exposed by our repository layer, instead of specific data provider implementations. This makes it easier for data providers to be switched out in the long run, and even converted into Flutter plugins/packages.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The goal of our repository layer is to create a wrapper for our data layer, and facilitate communication with the Bloc layer. In doing this, the rest of our code base depends only on functions exposed by our repository layer, instead of specific data provider implementations. This makes it easier for data providers to be switched out in the long run, and even converted into Flutter plugins/packages.
The goal of our repository layer is to create a wrapper for our data layer and facilitate communication with the Bloc layer. In doing this, the rest of our code base depends only on functions exposed by our repository layer, instead of specific data provider implementations. This makes it easier to switch out data providers later, or even convert them into individual Flutter plugins/packages.


### Creating Our Weather Repository Models

Update your directory structure to look like this. We will be creating a new `weather.dart` models file to contain only data we want to store, and another `models.dart` barrel file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Update your directory structure to look like this. We will be creating a new `weather.dart` models file to contain only data we want to store, and another `models.dart` barrel file.
Update your directory structure to look like the below. We will create a new `weather.dart` models file to contain only data we want to store, and another `models.dart` barrel file.

export 'weather.dart';
```

As we did in the previous section, run the following command to use `build_runner` to create our auto-generated models and factory methods.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As we did in the previous section, run the following command to use `build_runner` to create our auto-generated models and factory methods.
As we did in the previous step, run the following command to use `build_runner` to create our auto-generated models and factory methods.

}
```

Lastly, update the barrel file we created previously and we are done.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Lastly, update the barrel file we created previously and we are done.
Lastly, update the barrel file we created previously, and we are done with this step!


### Testing Our Weather Repository

To test our Weather Repository, we will use the [Mocktail](https://github.com/felangel/mocktail) library. Using this library, we will create mocks and insure that our weather repository's `getWeather` method works as it should. This includes testing when the API client fails, and making sure the `Weather` object returned is correct when the API call is successful.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To test our Weather Repository, we will use the [Mocktail](https://github.com/felangel/mocktail) library. Using this library, we will create mocks and insure that our weather repository's `getWeather` method works as it should. This includes testing when the API client fails, and making sure the `Weather` object returned is correct when the API call is successful.
To test our Weather Repository, we will use the [Mocktail](https://github.com/felangel/mocktail) library. Using this library, we will create mocks and insure that our weather repository's `getWeather` method works as it should. This includes testing when the API client fails, and making sure the returned `Weather` object is correct when the API call is successful.


## Business Logic Layer: Weather Model

In this section, we're going to implement our third weather model - this time for the weather feature of our main app. Note that we haven't been implementing the exact same model each time. In the API client package, our weather model contained all the info returned by the API. In the repository client package, our weather model contained only the data we wish to display in our app, and in this weather model, we will bake temperature settings into the weather model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this section, we're going to implement our third weather model - this time for the weather feature of our main app. Note that we haven't been implementing the exact same model each time. In the API client package, our weather model contained all the info returned by the API. In the repository client package, our weather model contained only the data we wish to display in our app, and in this weather model, we will bake temperature settings into the weather model.
In this section, we're going to implement our third weather model - this time for the weather feature of our main app. The goal of this model is to keep track of weather data displayed by our app and app settings.
Note that we haven't been implementing the exact same model each time. In the API client package, our weather model contained all the info returned by the API. In the repository client package, our weather model contained only the data we wish to display in our app. In this weather model, we will bake temperature settings into the weather model.


In this section, we're going to implement our third weather model - this time for the weather feature of our main app. Note that we haven't been implementing the exact same model each time. In the API client package, our weather model contained all the info returned by the API. In the repository client package, our weather model contained only the data we wish to display in our app, and in this weather model, we will bake temperature settings into the weather model.

Before we get started, lets update our project level dependencies to import the packages we've created and also the serialization/deserialization dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Before we get started, lets update our project level dependencies to import the packages we've created and also the serialization/deserialization dependencies.
Before we get started, let's update our project-level dependencies to import the packages we've created and the serialization/deserialization dependencies.

- assets/
```

We will be working in the `weather` features app, in our main project library.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We will be working in the `weather` features app, in our main project library.
We will be working inside the `weather` features app, in our main project library.

|-- weather.dart
```

The goal of our weather model is to keep track of weather data displayed by our app and also to keep track of settings. To keep track of settings (celsius, farenheit), create the temperature model in `weather`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The goal of our weather model is to keep track of weather data displayed by our app and also to keep track of settings. To keep track of settings (celsius, farenheit), create the temperature model in `weather`
To keep track of settings (celsius, farenheit), create the temperature model in `weather`

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the first sentence up to the top of this section

}
```

Lastly, to wrap this section up, run `build_runner` to create the auto generated file and methods, and also export our models in the barrel file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Lastly, to wrap this section up, run `build_runner` to create the auto generated file and methods, and also export our models in the barrel file
To wrap this section up, run `build_runner` to create the auto generated file and methods, then export our models in the barrel file.


## Business Logic Layer: Weather and Theme Cubits

In this tutorial, we will use HydratedCubits for our Bloc layer. HydratedCubits are essentially Cubits that can persist state across sessions when used in conjunction with HydratedStorage. In short, our HydratedCubits will keep track of state and expose methods which can be used to mutate state.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this tutorial, we will use HydratedCubits for our Bloc layer. HydratedCubits are essentially Cubits that can persist state across sessions when used in conjunction with HydratedStorage. In short, our HydratedCubits will keep track of state and expose methods which can be used to mutate state.
Now, we will use HydratedCubits for our Bloc layer to allow for theming. HydratedCubits are Cubits that can persist state across sessions when used in conjunction with HydratedStorage. In short, our HydratedCubits will keep track of state and expose methods which can be used to mutate state.

}
```

We will also need to keep track of what units (farenheit or celsius) our app is in.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We will also need to keep track of what units (farenheit or celsius) our app is in.
We will also need to keep track of what units (Fahrenheit or Celsius) our app is using.


### Weather Cubits

Finally! It's time to put together our Weather Cubit. Our Weather Cubit will expose the following methods:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Finally! It's time to put together our Weather Cubit. Our Weather Cubit will expose the following methods:
It's time to put together our Weather Cubit which will expose the following methods:

@felangel felangel added the documentation Documentation requested label Jun 7, 2021
@felangel felangel added this to In progress in Upgrade Documentation via automation Jun 7, 2021
Copy link
Owner

@felangel felangel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀 🎉

@felangel felangel merged commit f9a4de9 into felangel:master Jun 17, 2021
Upgrade Documentation automation moved this from In progress to Done Jun 17, 2021
Nomeleel pushed a commit to Nomeleel/bloc that referenced this pull request Jul 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Documentation requested
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

docs(flutter_weather): update documentation
4 participants