Category: Programming

  • assembly question.

    you should have a strong undestanding of ASCII, buffer, and assembly language of msp430 to solve the question

    Requirements: Complete

  • Optimization Model Jupiter notebook Problem.

    Please see the 4004P2.zip and the pdf (project2_) description file and write a python model in jupyter notebook for part 2 of the problem (The Problem of Optimizing Splitted Shipment) base on the code I provide (4004 P2 P1.ipynb). I have provided you the code for the first problem (The Problem of Optimizing Shipment). Please check the description more carefully. And write code in python. Also, there are 1 csv files that you need to use to complete the model.

    Please don’t use any AI sources.

    Requirements: Complete

  • Use SAP S/4HANA to record journal entries and generate finan…

    Go through the instructions and work as required

    Requirements: Complete

  • Apa yang perlu diketahui tentang [topik yang ingin ditanyaka…

    – Tujuan: Mengumpulkan informasi dasar dan poin penting yang wajib dipahami mengenai topik tertentu.

    – Cakupan: Bisa mencakup definisi, manfaat, komponen utama, aturan dasar, atau hal-hal yang perlu diperhatikan.

    – Cocok untuk: Siapa saja yang ingin memulai mempelajari suatu topik baru atau ingin mengetahui gambaran umum secara menyeluruh.

    Requirements:

  • What is the number of bone in a human body?

    What is the number of bone in a human body?

    Requirements:

  • OTH300 Foundations of Occupational

    I need a PowerPoint done I have examples

    Requirements:

  • My Name is Muhammad Zeeshan

    Muhammad Zeeshan

    Requirements:

  • Predictive Modeling in Marketing Analytics

    Predictive Modeling in Marketing Analytics

    Example Dataset:

    Objective:

    Students will work on a project that involves building a predictive model for a marketing analytics problem, such as predicting customer churn or identifying high-value customers. The goal is to apply regularization methods to improve the model’s performance and interpretability.

    Instructions:
    1. Data Collection: Obtain a dataset that includes customer demographics, purchase history, and other relevant features.
    2. Preprocessing: Preprocess the data by handling missing values, encoding categorical variables, and normalizing numerical features.
    3. Model Selection: Choose a predictive modeling technique, such as linear regression or logistic regression, and apply regularization methods such as Lasso or Ridge regression.
    4. Training: Train the model on the preprocessed dataset, using cross-validation to tune the regularization parameters.
    5. Evaluation: Evaluate the model’s performance using appropriate metrics, such as accuracy, precision, recall, or mean squared error.
    6. Interpretation: Interpret the model’s coefficients, discussing the impact of regularization on feature selection and model interpretability.
    7. Reporting: Document the entire process, including the methodology, results, and insights gained from the project, adhering to the Regularization Methods Project Rubric.
    Submission Requirements:

    Submit a written report that documents your entire project. The report should be structured and include the following sections:

    • File type: PDF or Word (.docx)
    • Introduction (brief overview of the problem and objective)
    • Data Collection (description and source of the dataset)
    • Data Preprocessing (explanation of how missing data, categorical variables, and scaling were handled)
    • Model Selection & Regularization (description of the chosen model(s) and regularization techniques used)
    • Training & Hyperparameter Tuning (cross-validation strategy and tuning process)
    • Evaluation (metrics used and interpretation of model performance)
    • Interpretation (analysis of feature importance and the impact of regularization on interpretability)
    • Conclusion (summary of findings and potential next steps)
    • References (cite any tools, libraries, or academic sources used)

    Requirements: i need video explaination.

  • Lab 5: File Data Analysis

    Data Analysis

    90 points

    allows a user to load one of two CSV files and then perform histogram analysis and plots for select variables on the datasets. The first dataset represents the population change for specific dates for U.S. regions. The second dataset represents Housing data over an extended period of time describing home age, number of bedrooms and other variables. The first row provides a column name for each dataset. The following columns should be used to perform analysis:

  • PopChange.csv:
    Pop Apr 1
    Pop Jul 1
    Change Pop
  • Housing.csv:
    AGE
    BEDRMS
    BUILT
    ROOMS
    UTILITY

    Notice for the Housing CSV file, there are more columns in the file than are required to be analyzed. You can and should still load each column.

    Specific statistics should include:

  • Count
    Mean
    Standard Deviation
    Min
    Max
    Histogram
  • Hints:

    1. Use the Pandas, Numpy, MatplotLib and other Python modules when appropriate.
    2. Be sure to install the required Python modules in your environment before you import or try to use them in your code. For example, pip install each of the required modules that are external Python libraries that you need.
    3. If an inappropriate entry is detected, the program should prompt for a correct value and continue to do so until a correct value is entered.
    4. Use comments to document your code
    5. Test with many combinations.
    6. Use pylint to verify the code style the goal is a 10!
    7. The user Interface should continue to run until the user indicates they are ready to exit.
    8. Be sure to review the previous readings and modules as you may need to use statistics and other modules to complete this lab.

    Score of Data Analysis,

    / 90

    Documentation and Testing

    22.5 points

    Document your testing results using your programming environment.

    You should also include and discuss your pylint results for the application.

    The test document should include a test table that includes the input values, the expected results and the actual results.

    A screen capture should be included that shows the actual test results of running each test case found in the test table.

    Be sure to include multiple test cases to provide full coverage for all code and for each function you develop and test.

    Requirements: answer

  • GetX Complete Guide with MVVM and Clean Architecture

    GetX Complete Guide with MVVM and Clean Architecture

    List of contents


    GetX Introduction

    GetX is a powerful Flutter framework with 3 main pillars:

    1. State Management

    • Reactive and easy to use
    • High performance
    • Minimal boilerplate

    2. Route Management (Navigation)

    • Navigation withoutcontext
    • Named routes
    • Middleware support

    3. Dependency Management (Inject Dependencies)

    • Lazy loading
    • Auto dispose
    • Smart management

    MVVM concept at GetX

    What is MVVM?

    MVVM = Model – View – ViewModel

    VIEW (UI)

    – Widget

    – No business logic

    – Only displays data

    Observes (Obx/GetBuilder)

    VIEWMODEL (Controller)

    – Business Logic

    – State Management

    – Input Validation

    – Communication with Repository

    Retrieving/Saving Data

    MODEL (Data Layer)

    – Repository

    – Provider (API, Database)

    – Data Models

    Mapping to GetX:

    • Model = models/, providers/, repositories/
    • View = views/ (Widget)
    • ViewModel = controllers/ (GetxController)

    Structure Folder

    Complete and Organized Structure

    lib/

    main.dart

    app/

    core/ # Code used throughout the app

    utils/ # Utility functions

    helpers.dart

    validators.dart

    values/ # Constants

    colors.dart

    strings.dart

    text_styles.dart

    widgets/ # Reusable widgets

    custom_button.dart

    loading_widget.dart

    data/ # DATA LAYER (Model)

    models/ # Data models

    user_model.dart

    product_model.dart

    providers/ # API calls, local DB

    api_provider.dart

    local_storage_provider.dart

    repositories/ # Bridge Controller Provider

    user_repository.dart

    product_repository.dart

    modules/ # APPLICATION FEATURES

    home/

    bindings/

    home_binding.dart

    controllers/

    home_controller.dart

    views/

    home_view.dart

    widgets/

    home_card.dart

    login/

    bindings/

    login_binding.dart

    controllers/

    login_controller.dart

    views/

    login_view.dart

    profile/

    bindings/

    profile_binding.dart

    controllers/

    profile_controller.dart

    views/

    profile_view.dart

    routes/ # ROUTING

    app_pages.dart # Definition of all routes

    app_routes.dart # Constant house routes

    pubspec.yaml

    Structure Explanation:

    1. /core – Shared Resources

    • utils/: Helper functions, validators, formatters
    • values/: Constants seperti colors, strings, API URLs
    • widgets/: Reusable widget for all apps

    2. /data – Data Layer (MODEL)

    • models/: Class model for data (User, Product, etc.)
    • providers/: Place for API calls, database operations
    • repositories/: Abstraction between controller and provider

    3. /modules – Feature Modules

    • Each feature has its own folder
    • Each module has:bindings, controllers, views

    4. /routes – Navigation

    • Centralized routing configuration

    Detailed Explanation of Each Layer

    1. MODEL LAYER

    a. Data Models (/data/models)

    A model is a representation of data, usually from an API or database.

    // lib/app/data/models/user_model.dart

    class User {

    final String id;

    final String name;

    final String email;

    final String? avatar;

    User({

    required this.id,

    required this.name,

    required this.email,

    this.avatar,

    });

    // From JSON to Object (parsing API response)

    factory User.fromJson(Map<String, dynamic> json) {

    return User(

    id: json[‘id’] ?? ”,

    name: json[‘name’] ?? ”,

    email: json[’email’] ?? ”,

    avatar: json[‘avatar’],

    );

    }

    // From Object to JSON (to send to API)

    Map<String, dynamic> toJson() {

    return {

    ‘id’: id,

    ‘name’: name,

    ’email’: email,

    ‘avatar’: avatar,

    };

    }

    // CopyWith for immutability

    User copyWith({

    String? id,

    String? name,

    String? email,

    String? avatar,

    }) {

    return User(

    id: id ?? this.id,

    name: name ?? this.name,

    email: email ?? this.email,

    avatar: avatar ?? this.avatar,

    );

    }

    }

    Example of a Complex Model with Nested Objects:

    // lib/app/data/models/product_model.dart

    class Product {

    final String id;

    final String name;

    final double price;

    final Category category;

    final List<String> images;

    Product({

    required this.id,

    required this.name,

    required this.price,

    required this.category,

    required this.images,

    });

    factory Product.fromJson(Map<String, dynamic> json) {

    return Product(

    id: json[‘id’],

    name: json[‘name’],

    price: (json[‘price’] as num).toDouble(),

    category: Category.fromJson(json[‘category’]),

    images: List<String>.from(json[‘images’] ?? []),

    );

    }

    }

    class Category {

    final String id;

    final String name;

    Category({required this.id, required this.name});

    factory Category.fromJson(Map<String, dynamic> json) {

    return Category(

    id: json[‘id’],

    name: json[‘name’],

    );

    }

    }

    b. Providers (/data/providers)

    The provider is responsible for communication with external data sources (API, Database, etc.).

    // lib/app/data/providers/api_provider.dart

    import ‘package:dio/dio.dart’;

    class ApiProvider {

    final Dio _dio = Dio(BaseOptions(

    baseUrl: ‘https://api.example.com’,

    connectTimeout: Duration(seconds: 5),

    receiveTimeout: Duration(seconds: 3),

    ));

    // GET request

    Future<Response> get(String path) async {

    try {

    final response = await _dio.get(path);

    return response;

    } on DioException catch (e) {

    throw _handleError(e);

    }

    }

    // POST request

    Future<Response> post(String path, Map<String, dynamic> data) async {

    try {

    final response = await _dio.post(path, data: data);

    return response;

    } on DioException catch (e) {

    throw _handleError(e);

    }

    }

    // PUT request

    Future<Response> put(String path, Map<String, dynamic> data) async {

    try {

    final response = await _dio.put(path, data: data);

    return response;

    } on DioException catch (e) {

    throw _handleError(e);

    }

    }

    // DELETE request

    Future<Response> delete(String path) async {

    try {

    final response = await _dio.delete(path);

    return response;

    } on DioException catch (e) {

    throw _handleError(e);

    }

    }

    // Error handling

    Exception _handleError(DioException error) {

    String errorMessage = ”;

    switch (error.type) {

    case DioExceptionType.connectionTimeout:

    errorMessage = ‘Connection timeout’;

    break;

    case DioExceptionType.sendTimeout:

    errorMessage = ‘Send timeout’;

    break;

    case DioExceptionType.receiveTimeout:

    errorMessage = ‘Receive timeout’;

    break;

    case DioExceptionType.badResponse:

    errorMessage = ‘Received invalid status code: ${error.response?.statusCode}’;

    break;

    case DioExceptionType.cancel:

    errorMessage = ‘Request cancelled’;

    break;

    default:

    errorMessage = ‘Connection error’;

    }

    return Exception(errorMessage);

    }

    }

    Provider for Local Storage:

    // lib/app/data/providers/local_storage_provider.dart

    import ‘package:get_storage/get_storage.dart’;

    class LocalStorageProvider {

    final _storage = GetStorage();

    // Save data

    Future<void> write(String key, dynamic value) async {

    await _storage.write(key, value);

    }

    // Read data

    T? read<T>(String key) {

    return _storage.read<T>(key);

    }

    // Delete data

    Future<void> remove(String key) async {

    await _storage.remove(key);

    }

    // Delete all data

    Future<void> clearAll() async {

    await _storage.erase();

    }

    }

    c. Repositories (/data/repositories)

    Repository isbridgebetween the Controller and the Provider. This abstraction eliminates the need for the controller to know the details of how data is retrieved.

    // lib/app/data/repositories/user_repository.dart

    import ‘../models/user_model.dart’;

    import ‘../providers/api_provider.dart’;

    class UserRepository {

    final ApiProvider _apiProvider;

    UserRepository(this._apiProvider);

    // Get user by ID

    Future<User> getUser(String userId) async {

    try {

    final response = await _apiProvider.get(‘/users/$userId’);

    return User.fromJson(response.data);

    } catch (e) {

    throw Exception(‘Failed to fetch user: $e’);

    }

    }

    // Get all users

    Future<List<User>> getAllUsers() async {

    try {

    final response = await _apiProvider.get(‘/users’);

    final List<dynamic> usersJson = response.data;

    return usersJson.map((json) => User.fromJson(json)).toList();

    } catch (e) {

    throw Exception(‘Failed to fetch users: $e’);

    }

    }

    // Update user

    Future<User> updateUser(String userId, Map<String, dynamic> data) async {

    try {

    final response = await _apiProvider.put(‘/users/$userId’, data);

    return User.fromJson(response.data);

    } catch (e) {

    throw Exception(‘Failed to update user: $e’);

    }

    }

    // Delete user

    Future<void> deleteUser(String userId) async {

    try {

    await _apiProvider.delete(‘/users/$userId’);

    } catch (e) {

    throw Exception(‘Failed to delete user: $e’);

    }

    }

    }

    Repository with Caching:

    // lib/app/data/repositories/product_repository.dart

    import ‘../models/product_model.dart’;

    import ‘../providers/api_provider.dart’;

    import ‘../providers/local_storage_provider.dart’;

    class ProductRepository {

    final ApiProvider _apiProvider;

    final LocalStorageProvider _localStorageProvider;

    ProductRepository(this._apiProvider, this._localStorageProvider);

    Future<List<Product>> getProducts({bool forceRefresh = false}) async {

    // Check cache first

    if (!forceRefresh) {

    final cachedProducts = _localStorageProvider.read<List>(‘products’);

    if (cachedProducts != null && cachedProducts.isNotEmpty) {

    return cachedProducts

    .map((json) => Product.fromJson(json))

    .toList();

    }

    }

    // If cache is empty or force refresh, get from API

    try {

    final response = await _apiProvider.get(‘/products’);

    final List<dynamic> productsJson = response.data;

    // Simple cache

    await _localStorageProvider.write(‘products’, productsJson);

    return productsJson.map((json) => Product.fromJson(json)).toList();

    } catch (e) {

    throw Exception(‘Failed to fetch products: $e’);

    }

    }

    }


    2. VIEWMODEL LAYER (Controller)

    Controller isbrainfrom the application. This is where all the business logic is located.

    Basic Controller

    // lib/app/modules/home/controllers/home_controller.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/models/user_model.dart’;

    import ‘../../../data/repositories/user_repository.dart’;

    class HomeController extends GetxController {

    final UserRepository repository;

    HomeController(this.repository);

    // Reactive variables

    var isLoading = false.obs;

    var users = <User>[].obs;

    var errorMessage = ”.obs;

    // Lifecycle: called when the controller is initialized

    @override

    void onInit() {

    super.onInit();

    fetchUsers();

    }

    // Lifecycle: called when the controller is ready to use

    @override

    void onReady() {

    super.onReady();

    print(‘HomeController is ready’);

    }

    // Lifecycle: called when the controller is deleted

    @override

    void onClose() {

    print(‘HomeController is closed’);

    super.onClose();

    }

    // Business Logic: Fetch users

    Future<void> fetchUsers() async {

    try {

    isLoading.value = true;

    errorMessage.value = ”;

    final result = await repository.getAllUsers();

    users.value = result;

    } catch (e) {

    errorMessage.value = e.toString();

    Get.snackbar(

    ‘Error’,

    ‘Failed to load users’,

    snackPosition: SnackPosition.BOTTOM,

    );

    } finally {

    isLoading.value = false;

    }

    }

    // Business Logic: Refresh

    Future<void> refreshUsers() async {

    await fetchUsers();

    }

    }

    Controller with Form Validation

    // lib/app/modules/login/controllers/login_controller.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘../../../data/repositories/auth_repository.dart’;

    import ‘../../../routes/app_routes.dart’;

    class LoginController extends GetxController {

    final AuthRepository repository;

    LoginController(this.repository);

    // Form controllers

    final emailController = TextEditingController();

    final passwordController = TextEditingController();

    // Reactive variables

    var isLoading = false.obs;

    var isPasswordHidden = true.obs;

    // Validation

    String? validateEmail(String? value) {

    if (value == null || value.isEmpty) {

    return ‘Email cannot be empty’;

    }

    if (!GetUtils.isEmail(value)) {

    return ‘Invalid email format’;

    }

    return null;

    }

    String? validatePassword(String? value) {

    if (value == null || value.isEmpty) {

    return ‘Password cannot be empty’;

    }

    if (value.length < 6) {

    return ‘Password minimum 6 characters’;

    }

    return null;

    }

    // Toggle password visibility

    void togglePasswordVisibility() {

    isPasswordHidden.value = !isPasswordHidden.value;

    }

    // Login action

    Future<void> login() async {

    // Input validation

    final emailError = validateEmail(emailController.text);

    final passwordError = validatePassword(passwordController.text);

    if (emailError != null || passwordError != null) {

    Get.snackbar(‘Validation Error’, emailError ?? passwordError ?? ”);

    return;

    }

    try {

    isLoading.value = true;

    await repository.login(

    email: emailController.text,

    password: passwordController.text,

    );

    // Navigate to home

    Get.offAllNamed(Routes.HOME);

    } catch (e) {

    Get.snackbar(

    ‘Login Failed’,

    e.toString(),

    snackPosition: SnackPosition.BOTTOM,

    );

    } finally {

    isLoading.value = false;

    }

    }

    @override

    void onClose() {

    emailController.dispose();

    passwordController.dispose();

    super.onClose();

    }

    }

    Controller dengan Workers (Side Effects)

    // lib/app/modules/search/controllers/search_controller.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/repositories/product_repository.dart’;

    class SearchController extends GetxController {

    final ProductRepository repository;

    SearchController(this.repository);

    var searchQuery = ”.obs;

    var searchResults = [].obs;

    var isSearching = false.obs;

    @override

    void onInit() {

    super.onInit();

    // Debounce: wait for the user to finish typing (1 second) then search

    debounce(

    searchQuery,

    (_) => performSearch(),

    time: Duration(seconds: 1),

    );

    // Ever: run every time searchQuery changes

    ever(searchQuery, (_) {

    print(‘Search query changed to: ${searchQuery.value}’);

    });

    // Once: run only once when first changed

    once(searchQuery, (_) {

    print(‘First search performed’);

    });

    }

    void updateSearchQuery(String query) {

    searchQuery.value = query;

    }

    Future<void> performSearch() async {

    if (searchQuery.value.isEmpty) {

    searchResults.clear();

    return;

    }

    try {

    isSearching.value = true;

    final results = await repository.searchProducts(searchQuery.value);

    searchResults.value = results;

    } catch (e) {

    Get.snackbar(‘Error’, ‘Search failed: $e’);

    } finally {

    isSearching.value = false;

    }

    }

    }

    Types of Workers in GetX:

    1. ever: Called every time the observable changes
    2. once: Called only once when the observable changes for the first time
    3. debounce: Waits for the user to finish performing an action (e.g. typing) before the action is executed
    4. interval: Ignore changes within a specified time interval

    3. VIEW LAYER

    View isUI/Widget. Its task is only to display data, there should be no business logic.

    Basic View with GetView

    GetView<T>is a widget that automatically has access to the type controllerT.

    // lib/app/modules/home/views/home_view.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘../controllers/home_controller.dart’;

    class HomeView extends GetView<HomeController> {

    const HomeView({Key? key}) : super(key: key);

    @override

    Widget build(BuildContext context) {

    return Scaffold(

    appBar: AppBar(

    title: Text(‘Home’),

    actions: [

    IconButton(

    icon: Icon(Icons.refresh),

    onPressed: controller.refreshUsers,

    ),

    ],

    ),

    body: Obx(() {

    // Loading state

    if (controller.isLoading.value) {

    return Center(child: CircularProgressIndicator());

    }

    // Error state

    if (controller.errorMessage.value.isNotEmpty) {

    return Center(

    child: Column(

    mainAxisAlignment: MainAxisAlignment.center,

    children: [

    Text(controller.errorMessage.value),

    SizedBox(height: 16),

    ElevatedButton(

    onPressed: controller.fetchUsers,

    child: Text(‘Retry’),

    ),

    ],

    ),

    );

    }

    // Empty state

    if (controller.users.isEmpty) {

    return Center(child: Text(‘No users found’));

    }

    // Success state

    return ListView.builder(

    itemCount: controller.users.length,

    itemBuilder: (context, index) {

    final user = controller.users[index];

    return ListTile(

    leading: CircleAvatar(

    backgroundImage: NetworkImage(user.avatar ?? ”),

    ),

    title: Text(user.name),

    subtitle: Text(user.email),

    onTap: () {

    Get.toNamed(Routes.PROFILE, arguments: user.id);

    },

    );

    },

    );

    }),

    );

    }

    }

    View with Form

    // lib/app/modules/login/views/login_view.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘../controllers/login_controller.dart’;

    class LoginView extends GetView<LoginController> {

    const LoginView({Key? key}) : super(key: key);

    @override

    Widget build(BuildContext context) {

    return Scaffold(

    body: SafeArea(

    child: Padding(

    padding: EdgeInsets.all(24),

    child: Column(

    mainAxisAlignment: MainAxisAlignment.center,

    children: [

    // Logo

    FlutterLogo(size: 100),

    SizedBox(height: 48),

    // Email field

    TextField(

    controller: controller.emailController,

    decoration: InputDecoration(

    labelText: ‘Email’,

    border: OutlineInputBorder(),

    prefixIcon: Icon(Icons.email),

    ),

    keyboardType: TextInputType.emailAddress,

    ),

    SizedBox(height: 16),

    // Password field

    Obx(() => TextField(

    controller: controller.passwordController,

    obscureText: controller.isPasswordHidden.value,

    decoration: InputDecoration(

    labelText: ‘Password’,

    border: OutlineInputBorder(),

    prefixIcon: Icon(Icons.lock),

    suffixIcon: IconButton(

    icon: Icon(

    controller.isPasswordHidden.value

    ? Icons.visibility_off

    : Icons.visibility,

    ),

    onPressed: controller.togglePasswordVisibility,

    ),

    ),

    )),

    SizedBox(height: 24),

    // Login button

    Obx(() => SizedBox(

    width: double.infinity,

    height: 50,

    child: ElevatedButton(

    onPressed: controller.isLoading.value

    ? null

    : controller.login,

    child: controller.isLoading.value

    ? CircularProgressIndicator(color: Colors.white)

    : Text(‘Login’),

    ),

    )),

    ],

    ),

    ),

    ),

    );

    }

    }

    Reactive State: Obx vs GetBuilder

    1. Obx – Untuk reactive variables (.obs)

    Obx(() => Text(‘Count: ${controller.count.value}’))

    2. GetBuilder- For manual updates (more performance for complex data)

    GetBuilder<HomeController>(

    builder: (controller) => Text(‘Count: ${controller.count}’),

    )

    3. GetX Widget- Combination of dependency injection + reactive

    GetX<HomeController>(

    init: HomeController(),

    builder: (controller) => Text(‘Count: ${controller.count.value}’),

    )


    4. BINDINGS (Dependency Injection)

    Bindings connect the controller to its dependencies and perform lazy initialization.

    Basic Binding

    // lib/app/modules/home/bindings/home_binding.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/providers/api_provider.dart’;

    import ‘../../../data/repositories/user_repository.dart’;

    import ‘../controllers/home_controller.dart’;

    class HomeBinding extends Bindings {

    @override

    void dependencies() {

    // Lazy initialization: only created when needed

    Get.lazyPut<ApiProvider>(() => ApiProvider());

    Get.lazyPut<UserRepository>(() => UserRepository(Get.find()));

    Get.lazyPut<HomeController>(() => HomeController(Get.find()));

    }

    }

    Types of Dependency Injection in GetX:

    // 1. lazyPut – Created when first needed (most frequently used)

    Get.lazyPut(() => HomeController());

    // 2. put – Created immediately, even if not used yet

    Get.put(HomeController());

    // 3. putAsync – For async initialization

    Get.putAsync<SharedPreferences>(() async {

    return await SharedPreferences.getInstance();

    });

    // 4. create – Creates a new instance every time Get.find() is called

    Get.create(() => HomeController());

    Binding with Multiple Dependencies

    // lib/app/modules/profile/bindings/profile_binding.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/providers/api_provider.dart’;

    import ‘../../../data/providers/local_storage_provider.dart’;

    import ‘../../../data/repositories/user_repository.dart’;

    import ‘../../../data/repositories/auth_repository.dart’;

    import ‘../controllers/profile_controller.dart’;

    class ProfileBinding extends Bindings {

    @override

    void dependencies() {

    // Providers

    Get.lazyPut<ApiProvider>(() => ApiProvider());

    Get.lazyPut<LocalStorageProvider>(() => LocalStorageProvider());

    // Repositories

    Get.lazyPut<UserRepository>(

    () => UserRepository(Get.find()),

    );

    Get.lazyPut<AuthRepository>(

    () => AuthRepository(Get.find(), Get.find()),

    );

    // Controller

    Get.lazyPut<ProfileController>(

    () => ProfileController(Get.find(), Get.find()),

    );

    }

    }


    5. ROUTING

    a. Routes Constants

    // lib/app/routes/app_routes.dart

    abstract class Routes {

    static const SPLASH = ‘/splash’;

    static const LOGIN = ‘/login’;

    static const REGISTER = ‘/register’;

    static const HOME = ‘/home’;

    static const PROFILE = ‘/profile’;

    static const SETTINGS = ‘/settings’;

    static const PRODUCT_DETAIL = ‘/product-detail’;

    }

    b. Pages Configuration

    // lib/app/routes/app_pages.dart

    import ‘package:get/get.dart’;

    import ‘../modules/home/bindings/home_binding.dart’;

    import ‘../modules/home/views/home_view.dart’;

    import ‘../modules/login/bindings/login_binding.dart’;

    import ‘../modules/login/views/login_view.dart’;

    import ‘../modules/profile/bindings/profile_binding.dart’;

    import ‘../modules/profile/views/profile_view.dart’;

    import ‘app_routes.dart’;

    class AppPages {

    static const INITIAL = Routes.LOGIN;

    static final routes = [

    GetPage(

    name: Routes.LOGIN,

    page: () => LoginView(),

    binding: LoginBinding(),

    ),

    GetPage(

    name: Routes.HOME,

    page: () => HomeView(),

    binding: HomeBinding(),

    transition: Transition.fadeIn,

    ),

    GetPage(

    name: Routes.PROFILE,

    page: () => ProfileView(),

    binding: ProfileBinding(),

    transition: Transition.rightToLeft,

    ),

    ];

    }

    c. Navigation Methods

    // Navigate to new page

    Get.to(() => NextPage());

    Get.toNamed(Routes.HOME);

    // Navigation with arguments

    Get.toNamed(Routes.PROFILE, arguments: {‘userId’: ‘123’});

    // In the destination controller, accept the arguments:

    final userId = Get.arguments[‘userId’];

    // Navigate and delete previous page

    Get.off(() => HomePage());

    Get.offNamed(Routes.HOME);

    // Navigate and clear all previous pages (clear stack)

    Get.offAll(() => HomePage());

    Get.offAllNamed(Routes.HOME);

    // Back to previous page

    Get.back();

    // Return with data

    Get.back(result: {‘success’: true});

    // Return until a certain condition is met

    Get.until((route) => route.settings.name == Routes.HOME);

    d. Middleware

    Middleware is useful for guard routes (e.g. login check).

    // lib/app/middlewares/auth_middleware.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘../routes/app_routes.dart’;

    class AuthMiddleware extends GetMiddleware {

    @override

    int? get priority => 1;

    @override

    RouteSettings? redirect(String? route) {

    // Check if the user is logged in

    final isLoggedIn = Get.find<AuthService>().isLoggedIn;

    if (!isLoggedIn) {

    return RouteSettings(name: Routes.LOGIN);

    }

    return null; // null = continue to the requested route

    }

    }

    // Use in app_pages.dart:

    GetPage(

    name: Routes.HOME,

    page: () => HomeView(),

    binding: HomeBinding(),

    middlewares: [AuthMiddleware()],

    ),


    Complete Implementation

    Case Study: Todo App

    1. Model

    // lib/app/data/models/todo_model.dart

    class Todo {

    final String id;

    final String title;

    final String description;

    final bool isCompleted;

    final DateTime createdAt;

    Todo({

    required this.id,

    required this.title,

    required this.description,

    this.isCompleted = false,

    required this.createdAt,

    });

    factory Todo.fromJson(Map<String, dynamic> json) {

    return Todo(

    id: json[‘id’],

    title: json[‘title’],

    description: json[‘description’] ?? ”,

    isCompleted: json[‘isCompleted’] ?? false,

    createdAt: DateTime.parse(json[‘createdAt’]),

    );

    }

    Map<String, dynamic> toJson() {

    return {

    ‘id’: id,

    ‘title’: title,

    ‘description’: description,

    ‘isCompleted’: isCompleted,

    ‘createdAt’: createdAt.toIso8601String(),

    };

    }

    Todo copyWith({

    String? id,

    String? title,

    String? description,

    bool? isCompleted,

    DateTime? createdAt,

    }) {

    return Todo(

    id: id ?? this.id,

    title: title ?? this.title,

    description: description ?? this.description,

    isCompleted: isCompleted ?? this.isCompleted,

    createdAt: createdAt ?? this.createdAt,

    );

    }

    }

    2. Repository

    // lib/app/data/repositories/todo_repository.dart

    import ‘../models/todo_model.dart’;

    import ‘../providers/api_provider.dart’;

    class TodoRepository {

    final ApiProvider _apiProvider;

    TodoRepository(this._apiProvider);

    Future<List<Todo>> getAllTodos() async {

    try {

    final response = await _apiProvider.get(‘/todos’);

    final List<dynamic> todosJson = response.data;

    return allJson.map((json) => All.fromJson(json)).toList();

    } catch (e) {

    throw Exception(‘Failed to fetch todos: $e’);

    }

    }

    Future<Todo> createTodo(Todo todo) async {

    try {

    final response = await _apiProvider.post(‘/todos’, todo.toJson());

    return Todo.fromJson(response.data);

    } catch (e) {

    throw Exception(‘Failed to create todo: $e’);

    }

    }

    Future<Todo> updateTodo(String id, Todo todo) async {

    try {

    final response = await _apiProvider.put(‘/todos/$id’, todo.toJson());

    return Todo.fromJson(response.data);

    } catch (e) {

    throw Exception(‘Failed to update todo: $e’);

    }

    }

    Future<void> deleteTodo(String id) async {

    try {

    await _apiProvider.delete(‘/todos/$id’);

    } catch (e) {

    throw Exception(‘Failed to delete todo: $e’);

    }

    }

    }

    3. Controller

    // lib/app/modules/todo/controllers/todo_controller.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/models/todo_model.dart’;

    import ‘../../../data/repositories/todo_repository.dart’;

    class TodoController extends GetxController {

    final TodoRepository repository;

    TodoController(this.repository);

    var todos = <Todo>[].obs;

    var isLoading = false.obs;

    var filter = TodoFilter.all.obs;

    @override

    void onInit() {

    super.onInit();

    fetchTodos();

    }

    // Get filtered todos

    List<Todo> get filteredTodos {

    switch (filter.value) {

    case TodoFilter.completed:

    return todos.where((todo) => todo.isCompleted).toList();

    case TodoFilter.active:

    return todos.where((all) => !all.isCompleted).toList();

    default:

    return all;

    }

    }

    // Get count

    int get completedCount => todos.where((t) => t.isCompleted).length;

    int get activeCount => todos.where((t) => !t.isCompleted).length;

    Future<void> fetchTodos() async {

    try {

    isLoading.value = true;

    final result = await repository.getAllTodos();

    everyone.value = result;

    } catch (e) {

    Get.snackbar(‘Error’, ‘Failed to fetch todos’);

    } finally {

    isLoading.value = false;

    }

    }

    Future<void> addTodo(String title, String description) async {

    try {

    final newTodo = Todo(

    id: DateTime.now().toString(),

    title: title,

    description: description,

    createdAt: DateTime.now(),

    );

    final created = await repository.createTodo(newTodo);

    todos.add(created);

    Get.snackbar(‘Success’, ‘Todo added successfully’);

    } catch (e) {

    Get.snackbar(‘Error’, ‘Failed to add todo’);

    }

    }

    Future<void> toggleTodo(Todo todo) async {

    try {

    final updated = todo.copyWith(isCompleted: !todo.isCompleted);

    await repository.updateAll(all.id, updated);

    final index = todos.indexWhere((t) => t.id == todo.id);

    todos[index] = updated;

    } catch (e) {

    Get.snackbar(‘Error’, ‘Failed to update todo’);

    }

    }

    Future<void> deleteTodo(String id) async {

    try {

    await repository.deleteTodo(id);

    everyone.removeWhere((everything) => everything.id == id);

    Get.snackbar(‘Success’, ‘Todo deleted’);

    } catch (e) {

    Get.snackbar(‘Error’, ‘Failed to delete todo’);

    }

    }

    void setFilter(TodoFilter newFilter) {

    filter.value = newFilter;

    }

    }

    enum TodoFilter { all, active, completed }

    4. View

    // lib/app/modules/todo/views/todo_view.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘../controllers/todo_controller.dart’;

    class TodoView extends GetView<TodoController> {

    const TodoView({Key? key}) : super(key: key);

    @override

    Widget build(BuildContext context) {

    return Scaffold(

    appBar: AppBar(

    title: Text(‘My Todos’),

    bottom: PreferredSize(

    preferredSize: Size.fromHeight(50),

    child: _buildFilterTabs(),

    ),

    ),

    body: Obx(() {

    if (controller.isLoading.value) {

    return Center(child: CircularProgressIndicator());

    }

    if (controller.filteredTodos.isEmpty) {

    return Center(child: Text(‘No todos found’));

    }

    return ListView.builder(

    itemCount: controller.filteredTodos.length,

    itemBuilder: (context, index) {

    final todo = controller.filteredTodos[index];

    return _buildTodoItem(todo);

    },

    );

    }),

    floatingActionButton: FloatingActionButton(

    onPressed: _showAddTodoDialog,

    child: Icon(Icons.add),

    ),

    bottomNavigationBar: _buildBottomBar(),

    );

    }

    Widget _buildFilterTabs() {

    return Obx(() => Row(

    mainAxisAlignment: MainAxisAlignment.spaceEvenly,

    children: [

    _buildFilterChip(‘All’, TodoFilter.all),

    _buildFilterChip(‘Active’, TodoFilter.active),

    _buildFilterChip(‘Completed’, TodoFilter.completed),

    ],

    ));

    }

    Widget _buildFilterChip(String label, TodoFilter filter) {

    final isSelected = controller.filter.value == filter;

    return ChoiceChip(

    label: Text(label),

    selected: isSelected,

    onSelected: (_) => controller.setFilter(filter),

    );

    }

    Widget _buildTodoItem(Todo todo) {

    return Dismissible(

    key: Key(todo.id),

    background: Container(

    color: Colors.red,

    alignment: Alignment.centerRight,

    padding: EdgeInsets.only(right: 16),

    child: Icon(Icons.delete, color: Colors.white),

    ),

    direction: DismissDirection.endToStart,

    onDismissed: (_) => controller.deleteTodo(todo.id),

    child: ListTile(

    leading: Checkbox(

    value: todo.isCompleted,

    onChanged: (_) => controller.toggleTodo(todo),

    ),

    title: Text(

    todo.title,

    style: TextStyle(

    decoration: todo.isCompleted

    ? TextDecoration.lineThrough

    : TextDecoration.none,

    ),

    ),

    subtitle: Text(todo.description),

    ),

    );

    }

    Widget _buildBottomBar() {

    return Obx(() => Container(

    padding: EdgeInsets.all(16),

    child: Text(

    ‘${controller.activeCount} active ${controller.completedCount} completed’,

    textAlign: TextAlign.center,

    ),

    ));

    }

    void _showAddTodoDialog() {

    final titleController = TextEditingController();

    final descController = TextEditingController();

    Get.dialog(

    AlertDialog(

    title: Text(‘Add New Todo’),

    content: Column(

    mainAxisSize: MainAxisSize.min,

    children: [

    TextField(

    controller: titleController,

    decoration: InputDecoration(labelText: ‘Title’),

    ),

    SizedBox(height: 8),

    TextField(

    controller: descController,

    decoration: InputDecoration(labelText: ‘Description’),

    ),

    ],

    ),

    actions: [

    TextButton(

    onPressed: () => Get.back(),

    child: Text(‘Cancel’),

    ),

    ElevatedButton(

    onPressed: () {

    if (titleController.text.isNotEmpty) {

    controller.addTodo(

    titleController.text,

    descController.text,

    );

    Get.back();

    }

    },

    child: Text(‘Add’),

    ),

    ],

    ),

    );

    }

    }

    5. Binding

    // lib/app/modules/todo/bindings/todo_binding.dart

    import ‘package:get/get.dart’;

    import ‘../../../data/providers/api_provider.dart’;

    import ‘../../../data/repositories/todo_repository.dart’;

    import ‘../controllers/todo_controller.dart’;

    class TodoBinding extends Bindings {

    @override

    void dependencies() {

    Get.lazyPut<ApiProvider>(() => ApiProvider());

    Get.lazyPut<TodoRepository>(() => TodoRepository(Get.find()));

    Get.lazyPut<TodoController>(() => TodoController(Get.find()));

    }

    }

    6. Main.dart

    // lib/main.dart

    import ‘package:flutter/material.dart’;

    import ‘package:get/get.dart’;

    import ‘app/routes/app_pages.dart’;

    void main() {

    runApp(MyApp());

    }

    class MyApp extends StatelessWidget {

    @override

    Widget build(BuildContext context) {

    return GetMaterialApp(

    title: ‘Every App’,

    theme: ThemeData(

    primarySwatch: Colors.blue,

    useMaterial3: true,

    ),

    initialRoute: AppPages.INITIAL,

    getPages: AppPages.routes,

    debugShowCheckedModeBanner: false,

    );

    }

    }


    Best Practices

    1. Naming Conventions

    // File names: snake_case

    user_model.dart

    home_controller.dart

    api_provider.dart

    // Class names: PascalCase

    class UserModel {}

    class HomeController {}

    // Variables & methods: camelCase

    var userName = ”;

    void fetchUsers() {}

    // Constants: UPPER_SNAKE_CASE

    const API_BASE_URL = ‘https://api.example.com’;

    // Private members: prefix with _

    var _isLoading = false;

    void _handleError() {}

    2. Reactive Variables

    // GOOD: Use .obs for primitive data

    var count = 0.obs;

    var name = ”.obs;

    var isLoading = false.obs;

    // GOOD: Use Rx<Type> for objects and nullables

    var user = Rx<User?>(null);

    var selectedDate = Rx<DateTime>(DateTime.now());

    // GOOD: Use RxList, RxMap for collections

    var items = <String>[].obs;

    var settings = <String, dynamic>{}.obs;

    // BAD: Don’t use .obs for non-reactive data

    3. Controller Lifecycle

    class MyController extends GetxController {

    // 1. Constructor

    MyController(this.repository);

    // 2. onInit – Initial setup

    @override

    void onInit() {

    super.onInit();

    fetchData(); // Load data for the first time

    setupListeners(); // Setup workers

    }

    // 3. onReady – After the widget is ready

    @override

    void onReady() {

    super.onReady();

    // Action after UI is ready

    }

    // 4. onClose – Cleanup

    @override

    void onClose() {

    // Dispose controllers, cancel subscriptions

    textController.dispose();

    super.onClose();

    }

    }

    4. Error Handling Pattern

    Future<void> fetchData() async {

    try {

    isLoading.value = true;

    errorMessage.value = ”;

    final result = await repository.getData();

    data.value = result;

    } on NetworkException catch (e) {

    errorMessage.value = ‘Network error: ${e.message}’;

    Get.snackbar(‘Network Error’, e.message);

    } on ValidationException catch (e) {

    errorMessage.value = ‘Validation error: ${e.message}’;

    } catch (e) {

    errorMessage.value = ‘Unexpected error: $e’;

    Get.snackbar(‘Error’, ‘Something went wrong’);

    } finally {

    isLoading.value = false;

    }

    }

    5. Separation of Concerns

    // BAD: Business logic di View

    class HomeView extends StatelessWidget {

    @override

    Widget build(BuildContext context) {

    return ElevatedButton(

    onPressed: () async {

    // Don’t be like this!

    final response = await http.get(‘…’);

    final data = jsonDecode(response.body);

    },

    child: Text(‘Fetch’),

    );

    }

    }

    // GOOD: Business logic di Controller

    class HomeController extends GetxController {

    Future<void> fetchData() async {

    final response = await repository.getData();

    // Process data

    }

    }

    class HomeView extends GetView<HomeController> {

    @override

    Widget build(BuildContext context) {

    return ElevatedButton(

    onPressed: controller.fetchData,

    child: Text(‘Fetch’),

    );

    }

    }

    6. Use GetView When Possible

    // GOOD: Use GetView if you only need 1 controller

    class HomeView extends GetView<HomeController> {

    @override

    Widget build(BuildContext context) {

    return Text(controller.title); // Directly access the controller

    }

    }

    // If you need multiple controllers:

    class ComplexView extends StatelessWidget {

    @override

    Widget build(BuildContext context) {

    final homeCtrl = Get.find<HomeController>();

    final authCtrl = Get.find<AuthController>();

    return Column(

    children: [

    Text(homeCtrl.title),

    Text(authCtrl.userName),

    ],

    );

    }

    }

    7. Lazy Loading Dependencies

    // GOOD: LazyPut – only created when needed

    class HomeBinding extends Bindings {

    @override

    void dependencies() {

    Get.lazyPut(() => HomeController());

    }

    }

    // AVOID: Put – created immediately even if not used yet

    class HomeBinding extends Bindings {

    @override

    void dependencies() {

    Get.put(HomeController()); // Created directly

    }

    }

    8. Reusable Widgets

    // lib/app/core/widgets/custom_button.dart

    class CustomButton extends StatelessWidget {

    final String text;

    final VoidCallback onPressed;

    final bool isLoading;

    const CustomButton({

    required this.text,

    required this.onPressed,

    this.isLoading = false,

    });

    @override

    Widget build(BuildContext context) {

    return ElevatedButton(

    onPressed: isLoading ? null : onPressed,

    child: isLoading

    ? CircularProgressIndicator()

    : Text(text),

    );

    }

    }


    Tips & Tricks

    1. Snackbar, Dialog, BottomSheet without Context

    Snack bar

    Get.snackbar(

    ‘Title’,

    ‘Message’,

    snackPosition: SnackPosition.BOTTOM,

    backgroundColor: Colors.red,

    colorText: Colors.white,

    duration: Duration(seconds: 3),

    );

    // Dialog

    Get.defaultDialog(

    title: ‘Alert’,

    middleText: ‘Are you sure?’,

    onConfirm: () => Get.back(),

    onCancel: () => Get.back(),

    );

    // Custom Dialog

    Get.dialog(

    AlertDialog(

    title: Text(‘Custom Dialog’),

    content: Text(‘This is a custom dialog’),

    actions: [

    TextButton(

    onPressed: () => Get.back(),

    child: Text(‘OK’),

    ),

    ],

    ),

    );

    // Bottom Sheet

    Get.bottomSheet(

    Container(

    color: Colors.white,

    child: Column(

    children: [

    ListTile(

    leading: Icon(Icons.camera),

    title: Text(‘Camera’),

    onTap: () => Get.back(),

    ),

    ListTile(

    leading: Icon(Icons.photo),

    title: Text(‘Gallery’),

    onTap: () => Get.back(),

    ),

    ],

    ),

    ),

    );

    2. GetUtils Helper Functions

    // Email validation

    if (GetUtils.isEmail(email)) {

    // Valid email

    }

    // Phone validation

    if (GetUtils.isPhoneNumber(phone)) {

    // Valid phone

    }

    // URL validation

    if (GetUtils.isURL(url)) {

    // Valid URL

    }

    // Null check

    if (GetUtils.isNull(value)) {

    // Is null

    }

    // Number check

    if (GetUtils.isNum(value)) {

    // Is number

    }

    3. Platform Checks

    if (GetPlatform.isAndroid) {

    // Android specific code

    }

    if (GetPlatform.isIOS) {

    // iOS specific code

    }

    if (GetPlatform.isWeb) {

    // Web specific code

    }

    if (GetPlatform.isMobile) {

    // Mobile (Android or iOS)

    }

    4. Internationalization (i18n)

    // lib/app/translations/app_translations.dart

    class AppTranslations extends Translations {

    @override

    Map<String, Map<String, String>> get keys => {

    ‘en_US’: {

    ‘hello’: ‘Hello’,

    ‘welcome’: ‘Welcome @name’,

    },

    ‘id_ID’: {

    ‘hello’: ‘Halo’,

    ‘welcome’: ‘Welcome @name’,

    },

    };

    }

    // In main.dart

    GetMaterialApp(

    translations: AppTranslations(),

    locale: Locale(‘id’, ‘ID’),

    fallbackLocale: Locale(‘in’, ‘US’),

    );

    // Use in code

    Text(‘hello’.tr); // Output: Halo

    Text(‘welcome’.trParams({‘name’: ‘John’})); // Output: Welcome John

    // Change language

    Get.updateLocale(Locale(‘en’, ‘US’));

    5. Theme Management

    // Change theme

    Get.changeTheme(ThemeData.dark());

    Get.changeTheme(ThemeData.light());

    // Cek current theme

    if (Get.isDarkMode) {

    // Dark mode active

    }

    6. Smart Refresh

    class MyController extends GetxController {

    Future<void> refreshData() async {

    await fetchData();

    update([‘my-list’]); // Update hanya widget dengan id ‘my-list’

    }

    }

    // In view

    GetBuilder<MyController>(

    id: ‘my-list’,

    builder: (controller) => ListView(…),

    )

    7. StateMixin for Loading States

    class MyController extends GetxController with StateMixin<List<User>> {

    @override

    void onInit() {

    super.onInit();

    fetchUsers();

    }

    Future<void> fetchUsers() async {

    change(null, status: RxStatus.loading());

    try {

    final users = await repository.getUsers();

    change(users, status: RxStatus.success());

    } catch (e) {

    change(null, status: RxStatus.error(‘Failed to load’));

    }

    }

    }

    // In view

    controller.obx(

    (users) => ListView.builder(…), // Success

    onLoading: CircularProgressIndicator(),

    onError: (error) => Text(error ?? ‘Error’),

    onEmpty: Text(‘No data’),

    )

    8. Global Controllers

    // For controllers used in multiple places

    class AppController extends GetxController {

    var theme = ThemeMode.light.obs;

    var locale = Locale(‘en’, ‘US’).obs;

    void toggleTheme() {

    theme.value = theme.value == ThemeMode.light

    ? ThemeMode.dark

    : ThemeMode.light;

    Get.changeThemeMode(theme.value);

    }

    }

    // In main.dart

    void main() {

    Get.put(AppController(), permanent: true); // permanent = not auto dispose

    runApp(MyApp());

    }

    // Access from anywhere

    final appCtrl = Get.find<AppController>();

    appCtrl.toggleTheme();


    Conclusion

    GetX with MVVM provides:

    1. Clean Architecture- Clear separation between UI, Logic, and Data
    2. Testability- Easy to test because it is separate
    3. Scalability- Easy to develop for large projects
    4. Maintainability- Code is easy for the team to maintain and understand

    Key to Success:

    • Consistent with folder structure
    • Separate concerns (View, Controller, Repository)
    • Use Binding for dependency injection
    • Take advantage of GetX’s reactive programming
    • Follow best practices
    • Well documented code

    Resources:


    Made with for Flutter Developers

    Requirements: