{"id":40125,"date":"2024-10-08T03:50:25","date_gmt":"2024-10-08T09:20:25","guid":{"rendered":"https:\/\/www.solutionanalysts.com\/blog\/?p=40125"},"modified":"2024-10-08T03:50:25","modified_gmt":"2024-10-08T09:20:25","slug":"crafting-robust-state-management-in-flutter","status":"publish","type":"post","link":"https:\/\/www.solutionanalysts.com\/blog\/crafting-robust-state-management-in-flutter\/","title":{"rendered":"Bloc Essentials: Crafting Robust State Management in Flutter"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">As an experienced Flutter developer, you know the importance of maintaining a clean and manageable codebase, especially as your app scales. Understanding the BLoC State Management (Business Logic Component) serves as the foundation of Flutter, offering a structured approach that separates business logic from the UI.<\/p>\n<p><\/span><span style=\"font-weight: 400;\">BLoC operates by receiving events, processing them, and outputting new states. This clear separation ensures that your app&#8217;s business logic remains isolated, testable, and easy to maintain. By implementing BLoC in Flutter apps, you create a solid foundation for the app&#8217;s architecture, much like a well-designed blueprint guides the construction of a building.<\/p>\n<p><\/span><span style=\"font-weight: 400;\">In essence, BLoC is the backbone of state management in Flutter, providing a robust structure that allows your app to scale while keeping the codebase organized and efficient.\u00a0<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Why_Choose_BLoC_The_Mechanics_Behind_Flutters_Workflow\"><\/span><b>Why Choose BLoC? The Mechanics Behind Flutter\u2019s Workflow\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">In Flutter, the UI is reactive and continuously listens for changes in state. Without a well-defined state management system, this can lead to complex and hard-to-maintain codebases. BLoC streamlines this process by clearly defining how events trigger state changes, ensuring that your app remains responsive and maintainable as it grows.\u00a0<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Advantages_of_Using_BloC_in_Flutter\"><\/span><b>Advantages of Using BloC in Flutter:<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Separation of Concerns: Keep your business logic separate from the UI.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Scalability: Easily manage state changes as your app grows.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Testability: Isolated business logic makes unit testing straightforward. <\/span><\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Getting_Started_with_BLoC_in_Flutter_Setting_Up_the_Dependencies\"><\/span><b>Getting Started with BLoC in Flutter: Setting Up the Dependencies<\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">To start using BLoC in Flutter project, you need to add the necessary dependencies, you can add the following in pubspec.yaml file:\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Run flutter `pub get to install` the dependencies.\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Creating_Events_Initiating_State_Changes\"><\/span><b>Creating Events: Initiating State Changes\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Events in BLoC are inputs that trigger changes in state, every event represents an action that the user can perform, such as submitting a login form.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here\u2019s an example of creating a login event:\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\/\/ Define the base class for all events<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">abstract class LoginEvent {}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ Event: User submits login credentials<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginSubmitted extends LoginEvent {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final String username;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final String password;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">LoginSubmitted(this.username, this.password);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In this example, `LoginSubmitted` is an event that prompts the BLoC to start the login process.\u00a0<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Creating States: Reflecting the App&#8217;s Current Status\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">States in BLoC in Flutter represent the different stages your app can be in as a result of events. For a login process, you might have states like loading, success, or failure.\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Define_these_states\"><\/span><b>Define these states:\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><i><span style=\"font-weight: 400;\">\/\/ Define the base class for all states<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">abstract class LoginState {}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ State: Initial state before any action<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginInitial extends LoginState {}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ State: Loading state during the login process<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginLoading extends LoginState {}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ State: Success state after a successful login<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginSuccess extends LoginState {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final String token;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">LoginSuccess(this.token);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ State: Failure state after a failed login<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginFailure extends LoginState {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final String error;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">LoginFailure(this.error);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">These states help your app&#8217;s UI accurately reflect what\u2019s happening in the background, ensuring that users are always aware of the current process.\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Managing_BLoC_with_State_and_Events_Implementing_the_Logic\"><\/span><b>Managing BLoC with State and Events: Implementing the Logic\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Now that you have your events and states set up, you need to manage how these interact using BLoC. This is where the core business logic of your app lives.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here\u2019s how you can implement a LoginBloc to handle the login process:\u00a0<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginBloc extends Bloc&lt;LoginEvent, LoginState&gt; {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final UserRepository userRepository;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">LoginBloc(this.userRepository) : super(LoginInitial()) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">on&lt;LoginSubmitted&gt;((event, emit) async {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">emit(LoginLoading());<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">try {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">final token = await userRepository.authenticate(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">username: event.username,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">password: event.password,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">emit(LoginSuccess(token));<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">} catch (error) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">emit(LoginFailure(error.toString()));<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">});<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In this example, when a LoginSubmitted event is triggered, the BLoC handles the event by authenticating the user through a repository and then updating the state based on the outcome.\u00a0<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<h2><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-40127\" src=\"https:\/\/www.solutionanalysts.com\/blog\/wp-content\/uploads\/2024\/10\/07-10-2024-02.jpg\" alt=\"Integrating BLoC with the UI: Bringing It All Together \" width=\"8075\" height=\"4575\" \/><\/h2>\n<h2><span class=\"ez-toc-section\" id=\"Integrating_BLoC_with_the_UI_Bringing_It_All_Together\"><\/span><b>Integrating BLoC with the UI: Bringing It All Together\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Now that you&#8217;ve implemented your BLoC with events and states, it&#8217;s time to see how it integrates with the UI. In Flutter, BLoC can be seamlessly connected to widgets which allows the UI to react to state changes in real-time.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s walk through an example of how to handle the login BLoC in the UI.\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_1_Providing_the_BLoC_to_the_Widget_Tree\"><\/span><b>Step 1: Providing the BLoC to the Widget Tree<\/b><b><i>\u00a0<\/i><\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">First, you need to make the LoginBloc available to the widgets that need it. You can do this by using the BlocProvider widget, which will inject the BLoC into the widget tree:\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">void main() {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final userRepository = UserRepository(dio: Dio());<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">runApp(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">BlocProvider(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">create: (context) =&gt; LoginBloc(userRepository),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">child: MyApp(),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class MyApp extends StatelessWidget {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">@override<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">Widget build(BuildContext context) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">return MaterialApp(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">home: LoginScreen(),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In this setup, LoginBloc is provided to the entire widget tree, making it accessible to any child widget that needs it.\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_2_Building_the_UI_Based_on_BLoC_State\"><\/span><b>Step 2: Building the UI Based on BLoC State<\/b><b><i>\u00a0<\/i><\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Next, you\u2019ll create a LoginScreen widget that reacts to the state changes in LoginBloc. Using the BlocBuilder widget, you can rebuild parts of the UI based on the current state.\u00a0<\/span><\/p>\n<p><b>Set up the login screen:\u00a0<\/b><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginScreen extends StatelessWidget {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">@override<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">Widget build(BuildContext context) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">return Scaffold(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">appBar: AppBar(title: Text(&#8216;Login&#8217;)),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">body: BlocBuilder&lt;LoginBloc, LoginState&gt;(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">builder: (context, state) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">if (state is LoginInitial) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return _buildLoginForm(context);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">} else if (state is LoginLoading) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return Center(child: CircularProgressIndicator());<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">} else if (state is LoginSuccess) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return Center(child: Text(&#8216;Login Successful!&#8217;));<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">} else if (state is LoginFailure) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return _buildLoginForm(context, error: state.error);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">} else {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return Container();<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">},<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">Widget _buildLoginForm(BuildContext context, {String? error}) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final usernameController = TextEditingController();<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final passwordController = TextEditingController();<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">return Padding(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">padding: const EdgeInsets.all(16.0),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">child: Column(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">children: [<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">if (error != null) Text(error, style: TextStyle(color: Colors.red)),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">TextField(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">controller: usernameController,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">decoration: InputDecoration(labelText: &#8216;Username&#8217;),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">TextField(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">controller: passwordController,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">decoration: InputDecoration(labelText: &#8216;Password&#8217;),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">obscureText: true,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">SizedBox(height: 16),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">ElevatedButton(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">onPressed: () {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">context.read&lt;LoginBloc&gt;().add(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">LoginSubmitted(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">usernameController.text,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">passwordController.text,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">},<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">child: Text(&#8216;Login&#8217;),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">],<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">),<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_3_Handling_State_Changes\"><\/span><b>Step 3: Handling State Changes<\/b><b><i>\u00a0<\/i><\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">In this example, the BlocBuilder listens to the LoginBloc and rebuilds the UI based on the current state:\u00a0<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>LoginInitial:<\/b><span style=\"font-weight: 400;\"> Displays the login form.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>LoginLoading:<\/b><span style=\"font-weight: 400;\"> This shows a loading spinner while the login request is in progress.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>LoginSuccess:<\/b><span style=\"font-weight: 400;\"> Displays a success message when the login is successful.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>LoginFailure:<\/b><span style=\"font-weight: 400;\"> Rebuilds the form and displays an error message if the login fails.\u00a0<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">The _buildLoginForm function handles the login form layout and submits the LoginSubmitted event to the BLoC when the user presses the login button.\u00a0<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"BloCs_Communication_Integrating_Different_BloCs\"><\/span><b>BloCs Communication: Integrating Different BloCs\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">In a complex app, you might have multiple BLoCs that need to communicate with each other. This ensures that different parts of your app remain synchronized.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For instance, a ProfileBloc might need to update when the user successfully logs in:\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ Bloc A: Manages the user&#8217;s login status<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class LoginBloc extends Bloc&lt;LoginEvent, LoginState&gt; {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ &#8230; (as above)<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\/\/ Bloc B: Manages the user&#8217;s profile<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class ProfileBloc extends Bloc&lt;ProfileEvent, ProfileState&gt; {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final LoginBloc loginBloc;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">ProfileBloc(this.loginBloc) : super(ProfileInitial()) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">loginBloc.stream.listen((loginState) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">if (loginState is LoginSuccess) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">\/\/ Load profile data after successful login<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">add(LoadProfile(loginState.token));<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">});<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This setup ensures that your app\u2019s different components remain in sync, improving both the user experience and code maintainability.\u00a0<\/span><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<h3><span class=\"ez-toc-section\" id=\"Using_Repositories_A_Key_Part_of_Your_Architecture\"><\/span><b>Using Repositories: A Key Part of Your Architecture\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><span style=\"font-weight: 400;\">A repository in BLoC serves as the data layer of your application. It abstracts the details of data fetching, whether from a network, database, or other sources. This separation ensures that your BLoC in Flutter only focuses on the business logic, making the code cleaner and more modular.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Take a look at how you can implement a UserRepository for managing login requests:\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">class UserRepository {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final Dio dio;<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">UserRepository({required this.dio});<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><i><span style=\"font-weight: 400;\">\u00a0<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">Future&lt;String&gt; authenticate({required String username, required String password}) async {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">final response = await dio.post(<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">&#8216;https:\/\/example.com\/api\/login&#8217;,<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">data: {&#8216;username&#8217;: username, &#8216;password&#8217;: password},<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">if (response.statusCode == 200) {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">return response.data[&#8216;token&#8217;];<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">} else {<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">\u00a0\u00a0<\/span><\/i> <i><span style=\"font-weight: 400;\">throw Exception(&#8216;Login failed&#8217;);<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">}<\/span><\/i><span style=\"font-weight: 400;\">\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">By using a repository, your BLoC remains focused on handling events and states, leaving the data management details to the repository. This approach not only keeps your codebase organized but also enhances reusability and testability.\u00a0<\/span><\/p>\n<h2><a href=\"https:\/\/www.solutionanalysts.com\/contact-us\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-40128 size-full\" src=\"https:\/\/www.solutionanalysts.com\/blog\/wp-content\/uploads\/2024\/10\/07-10-2024-03-1.jpg\" alt=\"\" width=\"8075\" height=\"2692\" \/><\/a><\/h2>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion_The_Power_of_BLoC_in_Flutter\"><\/span><b>Conclusion: The Power of BLoC in Flutter\u00a0<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">In this blog, we&#8217;ve covered how to architect a Flutter app using the BLoC pattern, focusing on event and state management, building a real-world app with BLoc, integrating BLoC with the UI, communicating between BLoCs, and using repositories. BLoC\u2019s clear separation of business logic and UI helps maintain a scalable and manageable codebase, ensuring your app remains robust as it grows.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you&#8217;re looking to build a scalable and efficient Flutter application with robust state management, our team of experts is here to help. At Solution Analysts, we offer a comprehensive range of IT services, from mobile app development to consulting and strategy. Reach out to us today to learn more about our services and how we can help you achieve your goals.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As an experienced Flutter developer, you know the importance of maintaining a clean and manageable codebase, especially as your app scales. Understanding the BLoC State Management (Business Logic Component) serves as the foundation of Flutter, offering a structured approach that separates business logic from the UI. BLoC operates by receiving events, processing them, and outputting [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":40129,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-40125","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hire-developer"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/posts\/40125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/comments?post=40125"}],"version-history":[{"count":1,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/posts\/40125\/revisions"}],"predecessor-version":[{"id":40130,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/posts\/40125\/revisions\/40130"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/media\/40129"}],"wp:attachment":[{"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/media?parent=40125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/categories?post=40125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.solutionanalysts.com\/blog\/wp-json\/wp\/v2\/tags?post=40125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}