🚀 User management app built in flutter using clean architecture, MVVM, get it, dio, RxDart, bloc, cubit, getX and provider

Overview

🔥 Go Rest app

In this project, we are going to build a user management app using Flutter. We have used the Go REST API to make HTTP request methods. This API provides all sorts of methods that we need: GET, POST, PUT, and DELETE. We will call all endpoints (users/todos/posts/comments) provided to us by the Go REST API using the Dio package in our app. We have performed different operations like selecting, adding, editing, and removing users, as well as user posts, todos, and comments.


🖼 Screenshots

User screen Create-update User Todo screen Post screen
Date picker Time picker Create-update post Comment Screen
Error state Empty state Warning dialog Progress dialog

🧩 Entity Relationship Diagram (ERD)

🚀 Features

  • Different implementations with separate modules based on state management solutions and software architectures

  • Clean architecture / MVVM architecture / simple layered architecture

  • Feature-first and Layer-first approach

  • Performing CRUD operation using Dio and go rest api

  • Converting JSON string to an equivalent dart object and vice versa with json serializable

  • Implementing Interceptors, Global configuration and timeout for api calls

  • Exception Handling with Dio interceptor, Dartz and freezed

  • Dependency injection with get it (Clean architecture / MVVM architecture version)

  • Displaying error type to the user through the alert dialogs

  • Colorize api info like request, response, body and exceptions in Debug console log

  • Read, create, update and delete user

  • Filter users by status activity or gender

  • Read, create, update and delete user todos

  • Filter todos by status

  • Read, create, update and delete user posts

  • Display, create and delete user comments for each post

  • Get date/time from user by Date/Time picker

  • Generic structure

  • State management with GetX | Bloc | Cubit | RxDart


🤝 Feature-first (Package-by-feature) and Layer-first (Package-by-layer)

In this repository two architectural approaches have been used. Feature-first (for clean architecture and simple layered architecture version) and Layer-first (for mvvm architecture version).

The feature-first approach demands that we create a new folder for every new feature that we add to our app. And inside that, we add the layers themselves as sub-folders. But in Layer-first approach, we add all the relevant files inside each feature folder, ensuring that they belong to the correct layer.


❗️ Api limitation

• The user endpoint contains ten user objects by default. If any of them are deleted, they will be replaced with a new JSON object. This means that the length of the user list will always be ten, and it is not possible to create more than ten user objects. This also applies if you want to add query parameters to the users.

• To use the request methods PUT, POST, PATCH, and DELETE, you need to provide an access token. This token must be passed with the "Authorization" header as a Bearer token. I have already included my own token in the app. However, if you receive an Unauthorized Error (401), please go to this link to obtain a new token and replace the old token in the api_config file located in the core directory.

• Please note that the data is not permanent and will be changed or deleted every 20 minutes to 1 hour.


🗂 Modules

Version Bloc Cubit Getx RxDart + Provider
Clean architecture version Source️ Source Source Source
MVVM architecture version Source Source️ Source️
Simple layered architecture version Source Source Source

📚 Dependencies (Clean architecture version (Feature-first))

Name GetX Cubit Bloc RxDart + Provider
flutter_bloc ✖️ ✔ ✔ ✖
provider ✖️ ✖ ✖ ✔
rxdart ✖️ ✖ ✖ ✔
get_it ✔️ ✔ ✔ ✔
GetX ✔️ ✖️ ✖️ ✖
dio ✔️ ✔️ ✔️ ✔
freezed ✖️ ✔️ ✔️ ✔
freezed_annotation ✖ ✔️ ✔️ ✔
json_annotation ✔️ ✔️ ✔️ ✔
json_serializable ✔️ ✔️ ✔️ ✔
build_runner ✔️ ✔️ ✔️ ✔
logger ✔️ ✔️ ✔️ ✔
dartz ✔️ ✖️ ✖️ ✖
flutter_spinkit ✔️ ✔️ ✔️ ✔
intl ✔️ ✔️ ✔️ ✔


📚 Dependencies (MVVM architecture version (Layer-first))

Name GetX Cubit Bloc
flutter_bloc ✖️ ✔ ✔
get_it ✔️ ✔ ✔
GetX ✔️ ✖️ ✖️
dio ✔️ ✔️ ✔️
freezed ✖️ ✔️ ✔️
freezed_annotation ✖ ✔️ ✔️
json_annotation ✔️ ✔️ ✔️
json_serializable ✔️ ✔️ ✔️
build_runner ✔️ ✔️ ✔️
logger ✔️ ✔️ ✔️
dartz ✔️ ✖️ ✖️
flutter_spinkit ✔️ ✔️ ✔️
intl ✔️ ✔️ ✔️

📚 Dependencies (Simple layered architecture version (Feature-first))

Name GetX Cubit Bloc
flutter_bloc ✖️ ✔ ✔
GetX ✔️ ✖️ ✖️
dio ✔️ ✔️ ✔️
freezed ✖️ ✔️ ✔️
freezed_annotation ✖ ✔️ ✔️
json_annotation ✔️ ✔️ ✔️
json_serializable ✔️ ✔️ ✔️
build_runner ✔️ ✔️ ✔️
logger ✔️ ✔️ ✔️
dartz ✔️ ✖️ ✖️
flutter_spinkit ✔️ ✔️ ✔️
intl ✔️ ✔️ ✔️



📂 Directory Structure (Clean architecture version + Bloc)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂bloc
│   │   │──bloc_helper.dart
│   │   └──generic_bloc_state.dart
│   │───📂usecase
│   │   └──usecase.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_config.dart
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
└───📂features
    │───📂user
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──user_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──user.dart
    │    │   │   └──user.g.dart
    │    │   └──📂repositories
    │    │       └──user_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──user_entity.dart
    │    │   │───📂repositories
    │    │   │   └──user_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_user_usecase.dart
    │    │   │   │──delete_user_usecase.dart
    │    │   │   │──get_users_usecase.dart
    │    │   │   └──update_user_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   │──user_bloc.dart
    │        │   └──user_event.dart
    │        │───📂screens
    │        │   └──user_list_screen.dart
    │        └───📂widgets
    │            └──status_container.dart
    │
    │───📂todo
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──todo_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──todo.dart
    │    │   │   └──todo.g.dart
    │    │   └──📂repositories
    │    │       └──todo_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──todo_entity.dart
    │    │   │───📂repositories
    │    │   │   └──todo_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_todo_usecase.dart
    │    │   │   │──delete_todo_usecase.dart
    │    │   │   │──get_todos_usecase.dart
    │    │   │   └──update_todo_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   │──todo_bloc.dart
    │        │   └──todo_event.dart
    │        │───📂screens
    │        │   └──todo_list_screen.dart
    │        └───📂widgets
    │            │──circle_container.dart
    │            └──todo_list_item.dart
    │───📂post
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──post_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──post.dart
    │    │   │   └──post.g.dart
    │    │   └──📂repositories
    │    │       └──post_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──post_entity.dart
    │    │   │───📂repositories
    │    │   │   └──post_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_post_usecase.dart
    │    │   │   │──delete_post_usecase.dart
    │    │   │   │──get_posts_usecase.dart
    │    │   │   └──update_post_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   │──post_bloc.dart
    │        │   └──post_event.dart
    │        └───📂screens
    │            │──create_post_screen.dart
    │            │──post_detail_screen.dart
    │            └──post_list_screen.dart
    └───📂comment
         │───📂data
         │   │──📂datasources
         │   │  └──comment_remote_data_source.dart
         │   │──📂models
         │   │   │──comment.dart
         │   │   └──comment.g.dart
         │   └──📂repositories
         │       └──comment_repository_impl.dart
         │───📂domain
         │   │───📂entities
         │   │   └──comment_entity.dart
         │   │───📂repositories
         │   │   └──comment_repository.dart
         │   │───📂usecases
         │   │   │──create_comment_usecase.dart
         │   │   │──delete_comment_usecase.dart
         │   │   └──get_comments_usecase.dart
         └── 📂presentation
             └───📂bloc
                 │──comment_bloc.dart
                 └──comment_event.dart




📂 Directory Structure (Clean architecture version + Cubit)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂cubit
│   │   │──generic_cubit.dart
│   │   └──generic_cubit_state.dart
│   │───📂usecase
│   │   └──usecase.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_config.dart
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
└───📂features
    │───📂user
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──user_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──user.dart
    │    │   │   └──user.g.dart
    │    │   └──📂repositories
    │    │       └──user_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──user_entity.dart
    │    │   │───📂repositories
    │    │   │   └──user_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_user_usecase.dart
    │    │   │   │──delete_user_usecase.dart
    │    │   │   │──get_users_usecase.dart
    │    │   │   └──update_user_usecase.dart
    │    └── 📂presentation
    │        │───📂cubit
    │        │   └──user_cubit.dart
    │        │───📂screens
    │        │   └──user_list_screen.dart
    │        └───📂widgets
    │            └──status_container.dart
    │
    │───📂todo
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──todo_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──todo.dart
    │    │   │   └──todo.g.dart
    │    │   └──📂repositories
    │    │       └──todo_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──todo_entity.dart
    │    │   │───📂repositories
    │    │   │   └──todo_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_todo_usecase.dart
    │    │   │   │──delete_todo_usecase.dart
    │    │   │   │──get_todos_usecase.dart
    │    │   │   └──update_todo_usecase.dart
    │    └── 📂presentation
    │        │───📂cubit
    │        │   └──todo_cubit.dart
    │        │───📂screens
    │        │   └──todo_list_screen.dart
    │        └───📂widgets
    │            │──circle_container.dart
    │            └──todo_list_item.dart
    │───📂post
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──post_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──post.dart
    │    │   │   └──post.g.dart
    │    │   └──📂repositories
    │    │       └──post_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──post_entity.dart
    │    │   │───📂repositories
    │    │   │   └──post_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_post_usecase.dart
    │    │   │   │──delete_post_usecase.dart
    │    │   │   │──get_posts_usecase.dart
    │    │   │   └──update_post_usecase.dart
    │    └── 📂presentation
    │        │───📂cubit
    │        │   └──post_cubit.dart
    │        └───📂screens
    │            │──create_post_screen.dart
    │            │──post_detail_screen.dart
    │            └──post_list_screen.dart
    └───📂comment
         │───📂data
         │   │──📂datasources
         │   │  └──comment_remote_data_source.dart
         │   │──📂models
         │   │   │──comment.dart
         │   │   └──comment.g.dart
         │   └──📂repositories
         │       └──comment_repository_impl.dart
         │───📂domain
         │   │───📂entities
         │   │   └──comment_entity.dart
         │   │───📂repositories
         │   │   └──comment_repository.dart
         │   │───📂usecases
         │   │   │──create_comment_usecase.dart
         │   │   │──delete_comment_usecase.dart
         │   │   └──get_comments_usecase.dart
         └── 📂presentation
             └───📂cubit
                 └──comment_cubit.dart




📂 Directory Structure (Clean architecture version + RxDart + Provider)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂bloc
│   │   └──generic_bloc_state.dart
│   │───📂usecase
│   │   └──usecase.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_config.dart
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
└───📂features
    │───📂user
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──user_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──user.dart
    │    │   │   └──user.g.dart
    │    │   └──📂repositories
    │    │       └──user_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──user_entity.dart
    │    │   │───📂repositories
    │    │   │   └──user_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_user_usecase.dart
    │    │   │   │──delete_user_usecase.dart
    │    │   │   │──get_users_usecase.dart
    │    │   │   └──update_user_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   │──user_bloc.dart
    │        │   └──user_event.dart
    │        │───📂screens
    │        │   └──user_list_screen.dart
    │        └───📂widgets
    │            └──status_container.dart
    │
    │───📂todo
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──todo_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──todo.dart
    │    │   │   └──todo.g.dart
    │    │   └──📂repositories
    │    │       └──todo_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──todo_entity.dart
    │    │   │───📂repositories
    │    │   │   └──todo_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_todo_usecase.dart
    │    │   │   │──delete_todo_usecase.dart
    │    │   │   │──get_todos_usecase.dart
    │    │   │   └──update_todo_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   │──todo_bloc.dart
    │        │   └──todo_event.dart
    │        │───📂screens
    │        │   └──todo_list_screen.dart
    │        └───📂widgets
    │            │──circle_container.dart
    │            └──todo_list_item.dart
    │───📂post
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──post_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──post.dart
    │    │   │   └──post.g.dart
    │    │   └──📂repositories
    │    │       └──post_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──post_entity.dart
    │    │   │───📂repositories
    │    │   │   └──post_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_post_usecase.dart
    │    │   │   │──delete_post_usecase.dart
    │    │   │   │──get_posts_usecase.dart
    │    │   │   └──update_post_usecase.dart
    │    └── 📂presentation
    │        │───📂bloc
    │        │   └──post_bloc.dart
    │        └───📂screens
    │            │──create_post_screen.dart
    │            │──post_detail_screen.dart
    │            └──post_list_screen.dart
    └───📂comment
         │───📂data
         │   │──📂datasources
         │   │  └──comment_remote_data_source.dart
         │   │──📂models
         │   │   │──comment.dart
         │   │   └──comment.g.dart
         │   └──📂repositories
         │       └──comment_repository_impl.dart
         │───📂domain
         │   │───📂entities
         │   │   └──comment_entity.dart
         │   │───📂repositories
         │   │   └──comment_repository.dart
         │   │───📂usecases
         │   │   │──create_comment_usecase.dart
         │   │   │──delete_comment_usecase.dart
         │   │   └──get_comments_usecase.dart
         └── 📂presentation
             └───📂bloc
                 └──comment_bloc.dart




📂 Directory Structure (Clean architecture version + GetX)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂controller
│   │   └──base_controller.dart
│   │───📂usecase
│   │   └──usecase.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_config.dart
│   │   │──api_base.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
└───📂features
    │───📂user
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──user_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──user.dart
    │    │   │   └──user.g.dart
    │    │   └──📂repositories
    │    │       └──user_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──user_entity.dart
    │    │   │───📂repositories
    │    │   │   └──user_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_user_usecase.dart
    │    │   │   │──delete_user_usecase.dart
    │    │   │   │──get_users_usecase.dart
    │    │   │   └──update_user_usecase.dart
    │    └── 📂presentation
    │        │───📂controller
    │        │   └──user_controller.dart
    │        │───📂screens
    │        │   └──user_list_screen.dart
    │        └───📂widgets
    │            └──status_container.dart
    │
    │───📂todo
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──todo_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──todo.dart
    │    │   │   └──todo.g.dart
    │    │   └──📂repositories
    │    │       └──todo_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──todo_entity.dart
    │    │   │───📂repositories
    │    │   │   └──todo_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_todo_usecase.dart
    │    │   │   │──delete_todo_usecase.dart
    │    │   │   │──get_todos_usecase.dart
    │    │   │   └──update_todo_usecase.dart
    │    └── 📂presentation
    │        │───📂controller
    │        │   └──todo_controller.dart
    │        │───📂screens
    │        │   └──todo_list_screen.dart
    │        └───📂widgets
    │            │──circle_container.dart
    │            └──todo_list_item.dart
    │───📂post
    │    │───📂data
    │    │   │──📂datasources
    │    │   │  └──post_remote_data_source.dart
    │    │   │──📂models
    │    │   │   │──post.dart
    │    │   │   └──post.g.dart
    │    │   └──📂repositories
    │    │       └──post_repository_impl.dart
    │    │───📂domain
    │    │   │───📂entities
    │    │   │   └──post_entity.dart
    │    │   │───📂repositories
    │    │   │   └──post_repository.dart
    │    │   │───📂usecases
    │    │   │   │──create_post_usecase.dart
    │    │   │   │──delete_post_usecase.dart
    │    │   │   │──get_posts_usecase.dart
    │    │   │   └──update_post_usecase.dart
    │    └── 📂presentation
    │        │───📂controller
    │        │   └──post_controller.dart
    │        └───📂screens
    │            │──create_post_screen.dart
    │            │──post_detail_screen.dart
    │            └──post_list_screen.dart
    └───📂comment
         │───📂data
         │   │──📂datasources
         │   │  └──comment_remote_data_source.dart
         │   │──📂models
         │   │   │──comment.dart
         │   │   └──comment.g.dart
         │   └──📂repositories
         │       └──comment_repository_impl.dart
         │───📂domain
         │   │───📂entities
         │   │   └──comment_entity.dart
         │   │───📂repositories
         │   │   └──comment_repository.dart
         │   │───📂usecases
         │   │   │──create_comment_usecase.dart
         │   │   │──delete_comment_usecase.dart
         │   │   └──get_comments_usecase.dart
         └── 📂presentation
             └───📂controller
                 └──comment_controller.dart




📂 Directory Structure (MVVM architecture version + Bloc)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂bloc
│   │   │──bloc_helper.dart
│   │   └──generic_bloc_state.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──api_config.dart
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
│───📂data
│   │───📂api
│   │    │───📂comment
│   │    │   └──comment_api.dart
│   │    │───📂post
│   │    │   └──post_api.dart
│   │    │───📂todo
│   │    │   └──todo_api.dart
│   │    └───📂user
│   │        └──user_api.dart
│   │    
│   └───📂model 
│        │───📂comment
│        │   │──comment.dart
│        │   └──comment.g.dart
│        │───📂post
│        │   │──post.dart
│        │   └──post.g.dart
│        │───📂todo
│        │   │──todo.dart
│        │   └──todo.g.dart
│        └───📂user
│            │──user.dart
│            └──user.g.dart 
│    
│───📂repository
│    │───📂comment
│    │   └──comment_repository.dart
│    │───📂post
│    │   └──post_repository.dart
│    │───📂todo
│    │   └──todo_repository.dart
│    └───📂user
│        └──user_repository.dart
│
│───📂view
│    │───📂post
│    │   └──📂screen
│    │      │──create_post_screen.dart
│    │      │──post_detail_screen.dart
│    │      └──post_list_screen.dart
│    │    
│    │───📂todo
│    │   │──📂screen
│    │   │  └──todo_list_screen.dart
│    │   └──📂widget
│    │      │──circle_container.dart
│    │      └──todo_list_item.dart
│    │
│    └───📂user
│        │──📂screen
│        │  └──user_list_screen.dart
│        └──📂widget
│           └──status_container.dart
│     
└───📂viewmodel
         │───📂comment
         │   └──📂bloc
         │      └──comment_bloc.dart
         │      └──comment_event.dart
         │───📂post
         │   └──📂bloc
         │      └──post_bloc.dart
         │      └──post_event.dart
         │───📂todo
         │   └──📂bloc
         │      │──todo_bloc.dart
         │      └──todo_event.dart
         └───📂user
             └──📂bloc
                │──user_bloc.dart
                └──user_event.dart




📂 Directory Structure (MVVM architecture version + Cubit)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂cubit
│   │   │──generic_cubit.dart
│   │   └──generic_cubit_state.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──api_config.dart
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
│───📂data
│   │───📂api
│   │    │───📂comment
│   │    │   └──comment_api.dart
│   │    │───📂post
│   │    │   └──post_api.dart
│   │    │───📂todo
│   │    │   └──todo_api.dart
│   │    └───📂user
│   │        └──user_api.dart
│   │    
│   └───📂model 
│        │───📂comment
│        │   │──comment.dart
│        │   └──comment.g.dart
│        │───📂post
│        │   │──post.dart
│        │   └──post.g.dart
│        │───📂todo
│        │   │──todo.dart
│        │   └──todo.g.dart
│        └───📂user
│            │──user.dart
│            └──user.g.dart 
│    
│───📂repository
│    │───📂comment
│    │   └──comment_repository.dart
│    │───📂post
│    │   └──post_repository.dart
│    │───📂todo
│    │   └──todo_repository.dart
│    └───📂user
│        └──user_repository.dart
│
│───📂view
│    │───📂post
│    │   └──📂screen
│    │      │──create_post_screen.dart
│    │      │──post_detail_screen.dart
│    │      └──post_list_screen.dart
│    │    
│    │───📂todo
│    │   │──📂screen
│    │   │  └──todo_list_screen.dart
│    │   └──📂widget
│    │      │──circle_container.dart
│    │      └──todo_list_item.dart
│    │
│    └───📂user
│        │──📂screen
│        │  └──user_list_screen.dart
│        └──📂widget
│           └──status_container.dart
│     
└───📂viewmodel
         │───📂comment
         │   └──📂cubit
         │      └──comment_cubit.dart
         │───📂post
         │   └──📂cubit
         │      └──post_cubit.dart
         │───📂todo
         │   └──📂cubit
         │      └──todo_cubit.dart
         └───📂user
             └──📂cubit
                └──user_cubit.dart




📂 Directory Structure (MVVM architecture version + GetX)

📂lib
│───main.dart  
│───di.dart  
│───📂common  
│   │───📂controller
│   │   └──base_controller.dart
│   │───📂repository
│   │   └──repository_helper.dart
│   │───📂network
│   │   │──api_helper.dart
│   │   │──api_result.dart
│   │   │──api_result.freezed.dart
│   │   │──dio_client.dart
│   │   │──dio_exception.dart
│   │   └──dio_interceptor.dart
│   │───📂widget
│   │   │──date_time_picker.dart
│   │   │──drop_down.dart
│   │   │──empty_widget.dart
│   │   │──popup_menu.dart
│   │   │──spinkit_indicator.dart
│   │   └──text_input.dart
│   └───📂dialog
│       │──create_dialog.dart
│       │──delete_dialog.dart
│       │──progress_dialog.dart
│       └──retry_dialog.dart
│───📂core
│   │──api_config.dart
│   │──app_asset.dart
│   │──app_extension.dart
│   │──app_string.dart
│   │──app_style.dart
│   └──app_theme.dart
│
│───📂data
│   │───📂api
│   │    │───📂comment
│   │    │   └──comment_api.dart
│   │    │───📂post
│   │    │   └──post_api.dart
│   │    │───📂todo
│   │    │   └──todo_api.dart
│   │    └───📂user
│   │        └──user_api.dart
│   │    
│   └───📂model 
│        │───📂comment
│        │   │──comment.dart
│        │   └──comment.g.dart
│        │───📂post
│        │   │──post.dart
│        │   └──post.g.dart
│        │───📂todo
│        │   │──todo.dart
│        │   └──todo.g.dart
│        └───📂user
│            │──user.dart
│            └──user.g.dart 
│    
│───📂repository
│    │───📂comment
│    │   └──comment_repository.dart
│    │───📂post
│    │   └──post_repository.dart
│    │───📂todo
│    │   └──todo_repository.dart
│    └───📂user
│        └──user_repository.dart
│
│───📂view
│    │───📂post
│    │   └──📂screen
│    │      │──create_post_screen.dart
│    │      │──post_detail_screen.dart
│    │      └──post_list_screen.dart
│    │    
│    │───📂todo
│    │   │──📂screen
│    │   │  └──todo_list_screen.dart
│    │   └──📂widget
│    │      │──circle_container.dart
│    │      └──todo_list_item.dart
│    │
│    └───📂user
│        │──📂screen
│        │  └──user_list_screen.dart
│        └──📂widget
│           └──status_container.dart
│     
└───📂viewmodel
         │───📂comment
         │   └──📂controller
         │      └──comment_controller.dart
         │───📂post
         │   └──📂controller
         │      └──post_controller.dart
         │───📂todo
         │   └──📂controller
         │      └──todo_controller.dart
         └───📂user
             └──📂controller
                └──user_controller.dart


📂 Directory Structure (Simple layered architecture version + Cubit)

📂lib
 │───main.dart  
 │───📂common  
 │   │───📂cubit
 │   │   │──generic_cubit.dart
 │   │   └──generic_cubit_state.dart
 │   │───📂network
 │   │   │──api_base.dart
 │   │   │──api_result.dart
 │   │   │──api_result.freezed.dart
 │   │   │──dio_client.dart
 │   │   │──dio_exception.dart
 │   │   └──dio_interceptor.dart
 │   │───📂widget
 │   │   │──date_time_picker.dart
 │   │   │──drop_down.dart
 │   │   │──empty_widget.dart
 │   │   │──popup_menu.dart
 │   │   │──spinkit_indicator.dart
 │   │   └──text_input.dart 
 │   └───📂dialog
 │       │──create_dialog.dart
 │       │──delete_dialog.dart
 │       │──progress_dialog.dart
 │       └──retry_dialog.dart
 │───📂core 
 │   │──api_config.dart
 │   │──app_asset.dart
 │   │──app_extension.dart
 │   │──app_string.dart
 │   │──app_style.dart
 │   └──app_theme.dart
 └───📂features
     │───📂comment
     │    │───📂cubit
     │    │   └──comment_cubit.dart
     │    └───📂data
     │        │───📂model
     │        │   │──comment.dart
     │        │   └──comment.g.dart
     │        └───📂provider
     │            └──📂remote
     │               └──comment_api.dart
     │───📂post
     │    │───📂cubit
     │    │   └──post_cubit.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──post.dart
     │    │   │   └──post.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──psot_api.dart
     │    └───📂view  
     │        └──📂screen
     │           │──create_post_screen.dart
     │           │──post_detail_screen.dart
     │           └──post_list_screen.dart
     │───📂todo
     │    │───📂cubit
     │    │   └──todo_cubit.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──todo.dart
     │    │   │   └──todo.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──todo_api.dart
     │    └───📂view  
     │        │──📂screen
     │        │  └──todo_list_screen.dart
     │        └──📂widget
     │            │──circle_container.dart
     │            └──todo_list_item.dart
     └───📂user
          │───📂cubit
          │   └──user_cubit.dart
          │───📂data
          │   │───📂model
          │   │   │──user.dart
          │   │   └──user.g.dart
          │   └───📂provider
          │       └──📂remote
          │          └──user_api.dart
          └───📂view  
              │──📂screen
              │  └──user_list_screen.dart
              └──📂widget
                 └──status_container.dart

📂 Directory Structure (Simple layered architecture version + Bloc)

📂lib
 │───main.dart  
 │───📂common  
 │   │───📂bloc
 │   │   │──bloc_helper.dart
 │   │   └──generic_bloc_state.dart
 │   │───📂network
 │   │   │──api_base.dart
 │   │   │──api_result.dart
 │   │   │──api_result.freezed.dart
 │   │   │──dio_client.dart
 │   │   │──dio_exception.dart
 │   │   └──dio_interceptor.dart
 │   │───📂widget
 │   │   │──date_time_picker.dart
 │   │   │──drop_down.dart
 │   │   │──empty_widget.dart
 │   │   │──popup_menu.dart
 │   │   │──spinkit_indicator.dart
 │   │   └──text_input.dart 
 │   └───📂dialog
 │       │──create_dialog.dart
 │       │──delete_dialog.dart
 │       │──progress_dialog.dart
 │       └──retry_dialog.dart
 │───📂core 
 │   │──api_config.dart
 │   │──app_asset.dart
 │   │──app_extension.dart
 │   │──app_string.dart
 │   │──app_style.dart
 │   └──app_theme.dart
 └───📂features
     │───📂comment
     │    │───📂bloc
     │    │   │──comment_bloc.dart
     │    │   └──comment_event.dart
     │    └───📂data
     │        │───📂model
     │        │   │──comment.dart
     │        │   └──comment.g.dart
     │        └───📂provider
     │            └──📂remote
     │               └──comment_api.dart
     │───📂post
     │    │───📂bloc
     │    │   └──post_bloc.dart
     │    │   │──post_event.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──post.dart
     │    │   │   └──post.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──psot_api.dart
     │    └───📂view  
     │        └──📂screen
     │           │──create_post_screen.dart
     │           │──post_detail_screen.dart
     │           └──post_list_screen.dart
     │───📂todo
     │    │───📂bloc
     │    │   │──todo_bloc.dart
     │    │   └──todo_event.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──todo.dart
     │    │   │   └──todo.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──todo_api.dart
     │    └───📂view  
     │        │──📂screen
     │        │  └──todo_list_screen.dart
     │        └──📂widget
     │            │──circle_container.dart
     │            └──todo_list_item.dart
     └───📂user
          │───📂bloc
          │   │──user_bloc.dart
          │   └──user_event.dart
          │───📂data
          │   │───📂model
          │   │   │──user.dart
          │   │   └──user.g.dart
          │   └───📂provider
          │       └──📂remote
          │          └──user_api.dart
          └───📂view  
              │──📂screen
              │  └──user_list_screen.dart
              └──📂widget
                 └──status_container.dart

📂 Directory Structure (Simple layered architecture version + GetX)

📂lib
 │───main.dart  
 │───📂common  
 │   │───??controller
 │   │   └──base_controller.dart
 │   │───📂network
 │   │   │──api_base.dart
 │   │   │──dio_client.dart
 │   │   │──dio_exception.dart
 │   │   └──dio_interceptor.dart
 │   │───📂widget
 │   │   │──date_time_picker.dart
 │   │   │──drop_down.dart
 │   │   │──empty_widget.dart
 │   │   │──popup_menu.dart
 │   │   │──spinkit_indicator.dart
 │   │   └──text_input.dart 
 │   └───📂dialog
 │       │──create_dialog.dart
 │       │──delete_dialog.dart
 │       │──progress_dialog.dart
 │       └──retry_dialog.dart
 │───📂core 
 │   │──api_config.dart
 │   │──app_asset.dart
 │   │──app_extension.dart
 │   │──app_string.dart
 │   │──app_style.dart
 │   └──app_theme.dart
 └───📂features
     │───📂comment
     │    │───📂controller
     │    │   └──comment_controller.dart
     │    └───📂data
     │        │───📂model
     │        │   │──comment.dart
     │        │   └──comment.g.dart
     │        └───📂provider
     │            └──📂remote
     │               └──comment_api.dart
     │───📂post
     │    │───📂controller
     │    │   └──post_controller.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──post.dart
     │    │   │   └──post.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──psot_api.dart
     │    └───📂view  
     │        └──📂screen
     │           │──create_post_screen.dart
     │           │──post_detail_screen.dart
     │           └──post_list_screen.dart
     │───📂todo
     │    │───📂controller
     │    │   └──todo_controller.dart
     │    │───📂data
     │    │   │───📂model
     │    │   │   │──todo.dart
     │    │   │   └──todo.g.dart
     │    │   └───📂provider
     │    │       └──📂remote
     │    │          └──todo_api.dart
     │    └───📂view  
     │        │──📂screen
     │        │  └──todo_list_screen.dart
     │        └──📂widget
     │            │──circle_container.dart
     │            └──todo_list_item.dart
     └───📂user
          │───📂controller
          │   └──user_controller.dart
          │───📂data
          │   │───📂model
          │   │   │──user.dart
          │   │   └──user.g.dart
          │   └───📂provider
          │       └──📂remote
          │          └──user_api.dart
          └───📂view  
              │──📂screen
              │  └──user_list_screen.dart
              └──📂widget
                 └──status_container.dart



🎯 Other flutter projects

Project Name Stars
Japanese restaurant app GitHub stars
Office furniture store app GitHub stars
Ecommerce app GitHub stars
You might also like...

Getx and Dio APi-Integration - Flutter RestApi Integration using Dio

Getx and Dio APi-Integration - Flutter RestApi Integration using Dio

Flutter RestApi Integration using Dio. Click this image to find videos== //Crud

Nov 5, 2022

Music player application for android. It's uses MVVM architecture and Provider & ValueNotifier state management.

Music player application for android. It's uses MVVM architecture and Provider & ValueNotifier state management.

music-player-flutter Flutter music player application which is my personal project published to play store. Project structures are as following,

Jul 10, 2022

Menaclub app for admin using nodejs as backend,RestAPI,provider as statemangement and follows MVVM architecture

menzclub_admin A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started i

Nov 7, 2022

Touranment Manager app using Firebase ,provider and MVVM Architecture

tournament_lotter A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you starte

Nov 25, 2022

⚖️ A Flutter Architecture for small/medium/large/big large scale using Provider as State Management with Get It!

⚖️ A Flutter Architecture for small/medium/large/big large scale using  Provider as State Management with Get It!

Flutter Provider Architecture Mobile Application Developed in Flutter. Running on both mobile platforms, Android 🤖 & iOS 🍎 . About this app This app

Jan 4, 2023

Flutter-clean-architecture - A simple flutter project developed with TDD and using Clean Architecture principles.

Clean Architecture This is a study project to practice TDD and a good approach of Clean Architecture for flutter projects. It is based on Reso Coder s

Jul 21, 2022

Provider Demo - Simple Provider using provider update counter and apply a timer also increase and decrease that value by pressing buttons

Provider Demo - Simple Provider using provider update counter and apply a timer also increase and decrease that value by pressing buttons

state_management simple Provider using provider update counter and apply a timer

Feb 2, 2022

This repo is an example of clean architecture using the GetX state-management solution.

This repo is an example of clean architecture using the GetX state-management solution.

GetX Clean Architecture A Flutter Clean Architecture Using GetX. This repo is forked from: https://github.com/phamdinhduc795397/flutter-getx-clean-arc

Jan 3, 2023
Comments
  • What is the best approach for obtaining two different return types response model for our data source?

    What is the best approach for obtaining two different return types response model for our data source?

    Clean Architecture Version (Cubit)/lib/features/comment/data/datasources

    Suppose we have two distinct response models for the same data source, how can we obtain them? Is it necessary to create a new data_source dart file for each new model, or can we organize multiple response models using the same data source?

    1. User Model
    2. UserType Model
    question 
    opened by apptechxonia 14
  • What should I do if the classes in the data/model/ folder are not the ones that need to be displayed on the screen?

    What should I do if the classes in the data/model/ folder are not the ones that need to be displayed on the screen?

    For example, when I retrieve a user from an API, I store the data using a User class. class User { final int? id; final String name; } However, if I need to make other API requests, such as getting the user's role, I would use a Role class to store that data. class Role { final int? roleId; final String roleName; } Finally, I would return a UserVo class (which is typically done in Java) to the screen. class UserVo { final int? id; final String name; final int? roleId; final String roleName; } Since the same class is used in the bloc, screen, and repository, I'm not sure how to make the necessary changes. What is the usual approach for this? Also, I'm using #7 - MVVM Version (Bloc). I look forward to your reply. Thank you.

    question 
    opened by yxm9264 2
  • How to get the same instance of a Cubit in multiple screens using BlocProvider with get_it?

    How to get the same instance of a Cubit in multiple screens using BlocProvider with get_it?

    I have two screens, Screen A and Screen B. To redirect from Screen A to Screen B, I used the go_router implementation. I initialized the bloc in Screen A as shown below:

    MultiBlocProvider(
      providers: [
        BlocProvider(create: (context) => getIt<ScreenOneCubit>()),
        BlocProvider(create: (context) => getIt<GenericFormFieldCubit<FormzInput>>()),
      ],
      child: ScreenA(),
    );
    
    

    
For Screen B: 


    
BlocProvider.value(
      value: getIt<ScreenOneCubit>(),
      child: ScreenB(),
    );
    

    In Di.dart, I registered the ScreenOneCubit using



    getIt.registerFactory(
      () => ScreenOneCubit()
);
    
    

    To redirect from Screen A to Screen B, I used GoRouter.of(context).pushNamed("screenB”). I assumed that the BlocProvider.value in Screen B would get the same cubit instance as Screen A, but I was not expecting the same instance. How can I get the same instance as Screen A in Screen B?

    Requirement: I have a module consisting of 7 screens. Upon clicking a button on the first screen, I make an API call and receive a response that is necessary for screens 4 and 7. To utilize the data, I pass it through each screen. To simplify the process, I wish to use a single Cubit instance to handle this data and easily access it on the relevant page. Can you suggest any approaches to accomplish this?

    Initially, I tried using a singleton-lazy instead of registerFactory to get the Cubit instance. However, after pressing the "Back" button and returning to screen 1, I called the API using the "Next" button, and although the API was called successfully, the BlocListener I was using to listen to the state was no longer triggered. To make the BlocListener listener again on screen 1, I had to close the application. Therefore, I returned to using the registerFactory method.

    question 
    opened by apptechxonia 0
Owner
Sina
Flutter enthusiast
Sina
A basic boilerplate template for starting a Flutter GetX project. GetX, Dio, MVVM, get CLI, Localization, Pagination etc are implemented.

Flutter GetX Template (GetX, Dio, MVVM) This Flutter Template using GetX package for State management, routing and Dependency Injection (bindings). We

Hasan Abdullah 214 Jan 9, 2023
Flutter app using MVVM architecture pattern , dio , provider , intl packages.

News App Simple news application using free news API for fetching realtime data from the internet. Features -Used MVVM architecture pattern. Packages

null 3 Mar 25, 2022
Flutter bloc cubit test knowdge - Flutter bloc cubit test knowdge

Flutter Bloc Simple Api This project is using weather api for featch data and di

Waruna Kaushalya 0 Jan 3, 2022
💻 Flutter clean architecture using the bloc & cubit library for state management

Egymation ?? · This application was developed using a well-defined and decoupled architecture, following TDD (test-driven programming) as a working me

Mohaned Zekry 3 Nov 21, 2022
Flutter GetX Template (GetX, Dio, MVVM)

Flutter GetX Template (GetX, Dio, MVVM) This Flutter Template using GetX package for State management, routing and Dependency Injection (bindings). We

null 7 Dec 18, 2022
Flutter mvvm archi - Flutter Advanced Course - Clean Architecture With MVVM

flutter_mvvm_archi A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you start

Namesh Kushantha 0 Jan 8, 2022
will cover the GetX Named Route, GetX Route Transition, GetX Route Result, GetX Route Argument, GetX Route Parameter etc.

getx_playground 1-navigation #2-reactiv A new Fl 3-SimpleStateManagement 4-GetXControllerExample 5- DependencyExample 6-TranslationExample 7-ThemeExam

null 4 Nov 11, 2022
Ouday 25 Dec 15, 2022
A starter kit for beginner learns with Bloc pattern, RxDart, sqflite, Fluro and Dio to architect a flutter project. This starter kit build an App Store app as a example

Flutter Starter Kit - App Store Example A starter kit for beginner learns with Bloc pattern, RxDart, sqflite, Fluro and Dio to architect a flutter pro

kw101 678 Jan 8, 2023
clean architecture and clean code with flutter , with bloc and getx state managment .

example_bloc A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

Khaled ElTohamy 6 Aug 22, 2022