16
Adding BLoCs to Firestore Client App Pages

WHAT YOU WILL LEARN IN THIS CHAPTER

  • How to pass app‐wide state management between pages
  • How to apply local‐state management in the widget tree
  • How to apply the InheritedWidget as a provider to pass state between widgets and pages
  • How to use dependency injection to inject service classes to the BLoC classes to achieve platform independence
  • How to apply the LoginBloc class to the Login page
  • How to apply the AuthenticationBloc class to manage user credentials for app‐wide state management
  • How to apply the HomeBloc class to the home page to list, add, and delete journal entries
  • How to apply the JournalEditBloc to the journal edit page to add or modify an existing entry
  • How to build reactive widgets by implementing the StreamBuilder widget
  • How to use the ListView.separated constructor to build a list of journal entries with a divider line by using the Divider() widget
  • How to use the Dismissible widget to swipe and delete an entry
  • How to use the Dismissible widget confirmDismiss property to prompt a delete confirmation dialog
  • How to use the DropdownButton() widget to present a list of moods with the title, color, and icon rotation
  • How to apply the MoodIcons class to retrieve the mood title, color, rotation, and icon
  • How to apply the Matrix4 rotateZ() method to rotate icons according to the mood in conjunction with the MoodIcons class
  • How to apply the FormatDates class to format dates

In this chapter, you'll continue to edit and complete the mood journaling app you've worked on in Chapters 14 and 15. For your convenience, you can use the ch15_final_journal project as your starting point and make sure you add your GoogleService‐Info.plist file to the Xcode project and the google‐services.json file to the Android project that you downloaded in Chapter 14 from your Firebase console.

You'll learn how to apply the BLoC, service, provider, model, and utility classes to the UI widget pages. The benefit of using the BLoC pattern allows for separation of the UI widgets from the business logic. You'll learn how to use dependency injection to inject service classes into the BLoC classes. By using dependency injection, the BLoCs remain platform‐agnostic.

You'll also learn how to apply app‐wide state management by implementing the AuthenticationBlocProvider class to the main page. You'll learn how to pass state between pages and the widget tree by implementing the HomeBlocProvider and JournalEditBlocProvider classes. You'll learn how to create a Login page that implements the LoginBloc class to validate emails, passwords, and user credentials. You'll modify the home page and learn how to implement the HomeBloc class to handle the journal entries list and add and delete individual entries. You'll learn how to create the journal edit page that implements the JournalEditBloc class to add, modify, and save existing entries.

ADDING THE LOGIN PAGE

The Login page contains a TextField for entering the email address and a TextField for entering the password by obscuring the characters for privacy. You'll also add a button to log in the user and a button to create a new user account. You'll learn how to implement the LoginBloc class by using the StreamBuilder widget. You'll learn how to use dependency injection to inject the AuthenticationService()class to the LoginBloc class constructor, resulting in the LoginBloc being platform‐agnostic. See Figure 16.1 for an idea of how the final Login page will look.

Screenshot of Final Login page.

FIGURE 16.1: Final Login page

MODIFYING THE MAIN PAGE

The main page is the control center responsible for monitoring app‐wide state management. You'll learn how to implement the AuthenticationBlocProvider class as the main provider to the AuthenticationBloc class. You'll learn how to implement the HomeBlocProvider class as the provider to the HomeBloc class with the child property as the Home class and also to hold the state for the user uid. You'll learn how to apply the StreamBuilder widget to monitor the user's authentication status. When the user logs in, the widget directs the user to the home page, and when the user logs out, it directs the user to the Login page. See Figure 16.2 for the main page BLoC flow.

Illustration of main page BLoC flow.

FIGURE 16.2: Main page BLoC flow

MODIFYING THE HOME PAGE

The home page is responsible for showing a list of journal entries filtered by the logged‐in user uid and the ability to add, modify, and delete individual entries. In this section, you'll learn how to implement the AuthenticationBlocProvider as the provider for the AuthenticationBloc class. You'll learn how to implement the HomeBlocProvider class as the provider for the HomeBloc class. You'll learn how to apply the StreamBuilder widget to build the journal entries list by calling the ListView.separated constructor. The Dismissible widget is used to swipe on an item to delete the entry. You'll learn how to use the Dismissible widget confirmDismiss property to prompt the user with a delete confirmation dialog. You'll learn how to call the MoodIcons class to color and rotate icons according to the selected mood. You'll learn how to call the FormatDates class to format dates.

Note that I purposely didn't inject the MoodIcons and FormatDates classes into the HomeBloc and EditJournalBLoc classes to show that you can decide not to include certain utility classes in the BLoC. If you were to include them in these BLoCs, you would duplicate the MoodIcons and FormatDates methods into two different BLoCs. In Chapter 15's “Implementing the BLoC Pattern” section, you learned in the UI design guidelines to create a BLoC for each complex enough component. Another option is to create a MoodAndDatesBloc class to handle the MoodIcons and FormatDates classes (as abstract classes) and use the MoodAndDatesBloc class in both the home and edit entry pages. See Figure 16.3 for an idea of how the final home page will look.

Screenshot of final home page.

FIGURE 16.3: Final home page

ADDING THE EDIT JOURNAL PAGE

The edit journal page is responsible for adding and editing a journal entry. In this section, you'll learn how to create the journal edit page that implements the JournalEditBlocProvider as the provider for the JournalEditBloc class. You'll learn to use the StreamBuilder widget with the date, mood, note, and Cancel and Save buttons. You'll implement the showTimePicker() function to present the user with a calendar to choose a date. You'll learn how to use the DropdownButton() widget to present the user with a list of selectable moods with the icon, color, description, and mood icon rotation. You'll use the Matrix4 rotateZ() method to implement the mood icon rotation. You'll use the TextEditingController() constructor with the note TextField() widget. You'll learn how to call the MoodIcons class to color and rotate icons in the DropdownButton DropdownMenuItem selection list. You'll learn how to call the FormatDates class to format the selected date. See Figure 16.4 for the look of the final edit journal page.

Screenshot of final edit journal page.

FIGURE 16.4: Final edit journal page

SUMMARY

In this chapter, you completed the journal app that you started in Chapter 14. You applied the BLoC pattern to separate the UI widgets from the business logic. You implemented BLoC classes, BLoC providers, service classes, utility classes, model classes, and app‐wide and local‐state management. You passed app‐wide state management between pages and local‐state management in the widget tree by using providers (InheritedWidget) and BLoCs. You used dependency injection to inject service classes into the BLoC classes. You learned that the benefit of using dependency injection keeps the BLoC classes platform‐agnostic, giving the ability to share BLoC classes between different platforms like Flutter, AngularDart, or others.

You applied app‐wide state management by implementing the AuthenticationBlocProvider and AuthenticationBloc classes to the app's main page. You used the StreamBuilder widget to monitor the _authenticationBloc.user stream for user credential changes. When the user credential changes, the StreamBuilder builder rebuilds and appropriately navigates the user to the login or home page.

You applied the LoginBloc class to validate the user's credentials and email and password requirements. You overrided the initState() method to initialize the _loginBloc variable with the LoginBloc class by injecting the AuthenticationService() class without using a provider. Note that the reason you initialized the _loginBloc variable from the initState() and not the didChangeDependencies() is because the LoginBloc does not need a provider (InheritedWidget).

You used the StreamBuilder widget with the TextField widget to validate email and password values. The TextField widget's onChanged property calls the _loginBloc.emailChanged.add sink and the _loginBloc.passwordChanged.add sink to send the values to the LoginBloc Validators class. You used the StreamBuilder widget to listen to the _loginBloc.loginOrCreateButton stream to toggle Login or Create Account as the default button.

You applied the HomeBloc class to build a list of journal entries filtered by the user uid with the ability to add, modify, and delete entries. You accessed the AuthenticationBlocProvider and HomeBlocProvider classes by using the provider's of() method from the didChangeDependencies method. You used the StreamBuilder widget by calling the ListView.separated constructor to build the journal entries list. You used the Dismissible widget's confirmDismiss property to prompt the user with the delete confirmation dialog. You called the MoodIcons utility class to format mood icons and the FormatDates class to format dates.

You accessed the JournalEditBlocProvider class by using the provider's of() method from the didChangeDependencies method. You applied the JournalEditBloc class to add, edit, and save journal entries. You used the StreamBuilder widget to handle the date, mood, note, and Cancel and Save buttons. You implemented the showTimePicker() function to show a calendar and to use the DropdownButton() widget to present the user with a list of selectable moods. You used the Matrix4 rotateZ() method to rotate the mood icon according to mood. You used the MoodIcons class with the DropdownButton DropdownMenuItem to present the mood selection list. You used the FormatDates class to format the selected date.

image WHAT YOU LEARNED IN THIS CHAPTER

TOPIC KEY CONCEPTS
LoginBloc class You learned how to implement the LoginBloc class without a provider to handle the authentication credentials and to validate email and password requirements.
AuthenticationBloc class You learned how to implement the AuthenticationBloc class with the AuthenticationBlocProvider class to handle app‐wide state management in the main page.
HomeBloc class You learned how to implement the HomeBloc class with the HomeBlocProvider class to populate the ListView with journal entries by using the separated() constructor. You learned to use the HomeBloc class to add, modify, or delete existing journal entries.
JournalEditBloc class You learned how to implement the JournalEditBloc class without a provider to add or edit and save journal entries.
InheritedWidget class The AuthenticationBlocProvider, HomeBlocProvider, and JournalEditBlocProvider classes extend from the InheritedWidget class, and you learned how to access them from the didChangeDependencies() method and not the initState() method.
AuthenticationBlocProvider class You learned how to implement the AuthenticationBlocProvider as the provider for the AuthenticationBloc class for app‐wide authentication state management.
HomeBlocProvider class You learned how to implement the HomeBlocProvider class as the provider for the HomeBloc class.
Dependency injection You learned how to use dependency injection by injecting service classes to the BLoC classes. You learned that by injecting services, the BLoC classes remain platform‐agnostic.
StreamBuilder widget You learned how to implement the StreamBuilder widget to monitor a stream, and when a change occurs, the builder rebuilds the widget with the latest data.
ListView.separated constructor and Divider() widget You learned how to implement the ListView.separated constructor to build a list of journal entries separated by a Divider() widget.
Dismissible widget and confirmDismiss property You learned how to implement the Dismissible widget to swipe and delete a journal entry. You learned how to implement the Dismissible widget's confirmDismiss property to prompt a dialog to confirm deleting a journal entry.
DropdownButton() widget You learned how to implement the DropdownButton() widget to present a list of moods with the title, color, and icon rotation.
MoodIcons class You learned how to implement the MoodIcons class to retrieve the mood's properties like the title, color, rotation, and icon.
showTimePicker() function You learned how to implement the showTimePicker() function to present a calendar to choose a date.
Matrix4 rotateZ() method You learned how to implement the Matrix4 rotateZ() method to rotate an icon according to the selected mood.
FormatDates class You learned how to implement the FormatDates class to format dates.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset