flutter
/

GetX Services: Building App-Wide Services with GetxService

Last Sync: Today

On this page

11
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

GetX Services: Building App-Wide Services with GetxService

What is GetxService?

GetxService is a specialized class in GetX designed for app-wide services that live throughout the entire application lifecycle. Unlike GetxController, which is typically tied to a route and disposed when the route is closed, GetxService is never automatically disposed (unless manually deleted). This makes it perfect for shared resources like API clients, authentication managers, theme managers, database helpers, and any other singleton that should persist for the app's duration.

GetxService vs GetxController

Creating a Service

To create a service, extend GetxService instead of GetxController. You can add any methods and reactive state just like a controller.

DARTRead-only
1
class AuthService extends GetxService {
  // Reactive state
  var isLoggedIn = false.obs;
  var user = User().obs;

  Future<void> login(String email, String password) async {
    // API call
    await Future.delayed(Duration(seconds: 1));
    isLoggedIn.value = true;
    user.value = User(email: email);
  }

  void logout() {
    isLoggedIn.value = false;
    user.value = User();
  }

  @override
  void onInit() {
    super.onInit();
    // Initialize service (e.g., load token from storage)
    print('AuthService initialized');
  }
}

Registering a Service

Register a service using Get.put or Get.lazyPut, usually with permanent: true (though it's automatically permanent). You can also use Get.putAsync for async initialization.

DARTRead-only
1
// Simple registration
Get.put(AuthService());

// Lazy registration (created on first use)
Get.lazyPut(() => AuthService());

// Async initialization
Get.putAsync<AuthService>(() async {
  final service = AuthService();
  await service.init();
  return service;
});

Initialization with onInit and onReady

Services have the same lifecycle methods as controllers: onInit (called after instance creation) and onReady (called after the widget tree is ready). Use them for initializing data, setting up streams, or loading preferences.

DARTRead-only
1
class StorageService extends GetxService {
  late SharedPreferences _prefs;

  @override
  Future<void> onInit() async {
    super.onInit();
    _prefs = await SharedPreferences.getInstance();
  }

  void setString(String key, String value) => _prefs.setString(key, value);
  String? getString(String key) => _prefs.getString(key);
}

Accessing Services Anywhere

Once registered, you can access the service using Get.find<MyService>() from any controller, view, or utility class.

DARTRead-only
1
class HomeController extends GetxController {
  final auth = Get.find<AuthService>();

  void checkAccess() {
    if (auth.isLoggedIn.value) {
      // do something
    }
  }
}

Common Service Examples

DARTRead-only
1
class ApiService extends GetxService {
  final Dio _dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));

  Future<Map<String, dynamic>> get(String endpoint) async {
    final response = await _dio.get(endpoint);
    return response.data;
  }

  @override
  void onClose() {
    _dio.close();
    super.onClose();
  }
}
DARTRead-only
1
class ThemeService extends GetxService {
  var isDarkMode = false.obs;

  void toggleTheme() {
    isDarkMode.value = !isDarkMode.value;
    Get.changeThemeMode(isDarkMode.value ? ThemeMode.dark : ThemeMode.light);
  }
}
DARTRead-only
1
class StorageService extends GetxService {
  SharedPreferences? _prefs;

  Future<StorageService> init() async {
    _prefs = await SharedPreferences.getInstance();
    return this;
  }

  void saveToken(String token) => _prefs?.setString('token', token);
  String? getToken() => _prefs?.getString('token');
}

Best Practices

  • Use services for app-wide logic – API clients, auth, analytics, notifications.
  • Keep services stateless when possible – Prefer storing state in controllers; services should provide methods and data access.
  • Inject services via constructor – Makes testing easier: class MyController extends GetxController { final ApiService api; MyController(this.api); }.
  • Initialize async services in onInit – Use await there, and consider Get.putAsync for registration.
  • Dispose resources in onClose – Close database connections, cancel timers, etc.
  • Use Get.find inside controllers – Don't re‑register services.

Common Mistakes

  • ❌ Using GetxService for screen-specific logic – It will stay in memory forever. ✅ Use GetxController for per‑screen logic.
  • ❌ Forgetting to dispose resources – Even though services aren't disposed automatically, you should clean up in onClose if needed.
  • ❌ Registering the same service multiple times – Causes duplicates unless you use tags. ✅ Check Get.isRegistered before registering.
  • ❌ Assuming Get.put for service is lazy – It's not; use Get.lazyPut for deferred creation.

FAQ

  • Q: Do I need to mark a service as permanent?
    A: No, GetxService is automatically permanent. It will never be disposed unless you call Get.delete.
  • Q: Can I use reactive state in a service?
    A: Yes, services can have .obs variables and controllers can listen to them using Obx or workers.
  • Q: How do I test a service?
    A: You can instantiate it directly in tests. For integration, use Get.reset() to clear registrations.
  • Q: Can a service depend on another service?
    A: Yes, simply Get.find the dependent service inside the constructor or onInit.
  • Q: Should I use Get.put or Get.lazyPut for services?
    A: If the service is needed immediately (e.g., auth check on start), use Get.put with async init. Otherwise, lazy is fine.
  • Q: Can I use GetxService with bindings?
    A: Yes, you can register services in initialBinding or in per‑route bindings (though they will live beyond the route).

Conclusion

GetxService is a powerful tool for managing global, long‑lived dependencies in your Flutter app. By extending GetxService, you can create clean, testable services that stay alive throughout the app lifecycle. Combine them with GetX dependency injection and reactive state to build robust applications.

Try it yourself

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Register the service before app starts
    Get.put(AuthService());
    return GetMaterialApp(
      home: HomePage(),
    );
  }
}

// Simple Auth Service
class AuthService extends GetxService {
  var isLoggedIn = false.obs;
  var userName = ''.obs;

  void login(String name) {
    isLoggedIn.value = true;
    userName.value = name;
  }

  void logout() {
    isLoggedIn.value = false;
    userName.value = '';
  }

  @override
  void onInit() {
    super.onInit();
    print('AuthService initialized');
  }
}

class HomePage extends StatelessWidget {
  final auth = Get.find<AuthService>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('GetX Service Demo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() => Text(
              auth.isLoggedIn.value
                  ? 'Welcome, ${auth.userName.value}'
                  : 'Not logged in',
              style: TextStyle(fontSize: 24),
            )),
            SizedBox(height: 20),
            if (!auth.isLoggedIn.value)
              ElevatedButton(
                onPressed: () => auth.login('Flutter User'),
                child: Text('Login'),
              ),
            if (auth.isLoggedIn.value)
              ElevatedButton(
                onPressed: auth.logout,
                child: Text('Logout'),
              ),
          ],
        ),
      ),
    );
  }
}

Test Your Knowledge

Q1
of 3

What class should you extend to create an app-wide service in GetX?

A
GetxController
B
GetxService
C
GetxWidget
D
GetxApp
Q2
of 3

How do you register a service with asynchronous initialization?

A
Get.putAsync
B
Get.lazyPut
C
Get.create
D
Get.put
Q3
of 3

What lifecycle method is called when the service is first created?

A
onReady
B
onStart
C
onInit
D
initState

Previous

getx middleware

Next

getx storage

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.