How to Use Flutter Getx | Tips for Beginners to Advanced

Flutter GetX Package Explained

Know platform

You can use GetPlatform.isIOS to know if it’s iOS or not

You can do the similar operation GetPlatform.isANDROID and GetPltaform.isWeb

See the getx basic here

GetxService

You can use GetxService when you need to store data locally on the device in memory. For example, when you want to load token from the server and save it the device. This kind of service should extend GetxService. 

Another example would be when you want to load some data from the server or on the device you created some data and want to save it locally, then you should extend GetXService.

Another practice example would be when you have API client class (that brings data from server or post data to server), then this class should extend GetxService.

class ApiClient extends GetConnect implements GetxService {
  late String token;
  final String appBaseUrl;
  final SharedPreferences sharedPreferences;
  late Map<String, String> _mainHeaders;

  ApiClient({required this.sharedPreferences, required this.appBaseUrl}) {
    baseUrl = appBaseUrl;
    timeout = Duration(seconds: 30);
    token = sharedPreferences.getString(AppConstants.TOKEN)??"";
    _mainHeaders = {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer $token',
    };
  }

See that, this class implements GetxService and we are passing token and other important properties. We also passed base url.

Most of the time, you would use GetConnect and GetxService together.

Then at the same time, your controller constructor must pass initialize values for baseUrl and timeout property.

You can also watch the video below

 

GetConnect

GetConnect is an easy way to make requests and fetch data . Lot of time GetConnect and GetxService work together.  You can simply extend GetConnect and implements GetxService. If you want to use the http get() method of Getx, then your controller must extends GetConnect.

Because of GetConnect, you app won't crash suddenly. See the below example

class ApiClient extends GetConnect implements GetxService {
  late String token;
  final String appBaseUrl;
  final SharedPreferences sharedPreferences;
  late Map<String, String> _mainHeaders;

  ApiClient({required this.sharedPreferences, required this.appBaseUrl}) {
    baseUrl = appBaseUrl;
    timeout = Duration(seconds: 30);
    token = sharedPreferences.getString(AppConstants.TOKEN)??"";
    _mainHeaders = {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer $token',
    };
  }

We extend GetConnect, and in the constructor, we pass base url and timeout property.

GetConnect supports get/post/put/delete request.  If you have a method for getting Data name getData, then inside getData, you can use get() request

Future<Response> getData(String uri, {Map<String, dynamic> query, String contentType,
  Map<String, String> headers, Function(dynamic) decoder,
}) async {
  try {

    Response response = await get(
      uri,
      contentType: contentType,
      query: query,
      headers: headers ?? _mainHeaders,
      decoder: decoder,
    );
    response = handleResponse(response);

    return response;
  } catch (e) {
    return Response(statusCode: 1, statusText: e.toString());
  }
}

Here getData is using get() request to retrieve or fetch data from the server. Get() Request returns Response object. 

So if you wan to use Get(), Post(), Delete() and Update() method of Getx state management, your controller must extend GetConnect and GetxService.

GetConnect learn more here

 

Routing with Parameters

GetPage() in Getx is very interesting and you can do many things with it. It takes two parameters name and page

GetPage(name:"route name", ()=>page());

The first parameter name, you can make it dynamic. You can define a variable for that name like

String routeName="/anyname";
GetPage(name:routeName, ()=>page());

So next time you can just change the routeName value. It's very convenient if your project is very big.

The fuction it takes you can also do many things with it. For example, instead of fat arrow function, you can return a function like below

String routeName="/anyname";
GetPage(name:routeName, (){
   "your logic goes here"
    return Page();
});

After doing your logic you can even send parameters with it.

    GetPage(name: verification, page: () {
      List<int> _decode = base64Decode(Get.parameters['pass']);
      String _data = utf8.decode(_decode);
      return VerificationScreen(
        number: Get.parameters['number'], fromSignUp: Get.parameters['page'] == signUp, token: Get.parameters['token'], password: _data,
      );
    }),

The above function should give you better idea, what you can do with GetPage() function.

You can define all of your routes in a list

Class RouteHelper{  
//variables to match the name property of the GetPage()
......
.....
static List<GetPage> routes = [
    GetPage(name: initial, page: () => getRoute(DashboardScreen(pageIndex: 0))),
    GetPage(name: splash, page: () => SplashScreen(orderID: Get.parameters['id'] == 'null' ? null : Get.parameters['id'])),
    GetPage(name: language, page: () => ChooseLanguageScreen(fromMenu: Get.parameters['page'] == 'menu')),
    GetPage(name: onBoarding, page: () => OnBoardingScreen()),
    GetPage(name: signIn, page: () => SignInScreen(
      exitFromApp: Get.parameters['page'] == signUp || Get.parameters['page'] == splash || Get.parameters['page'] == onBoarding,
    ))
];

}

At the same time you can delcare name properties in your same route class.

class RouteHelper{
  ...............
  ...............
  static const String signIn = '/sign-in';
  static const String signUp = '/sign-up';
  .............
  ..............
}

Then from your view you can access them. For example you can access the sign up or sign in route like below

 Get.toNamed(RouteHelper.signUp)

 

Worker functions in Getx

If you have long running process, getx makes it much easier to keep track of it. For example you can use ever() function to keep track of the user authentication. 

In your getx AuthController can do like below

    _firebaseUser = Rx<User?>(auth.currentUser);
    _firebaseUser.bindStream(auth.userChanges());
    ever(_firebaseUser, _setScreen);

Here ever() function is a worker function, since we use this function, Whatever happens to _firebaseUser, then immediately _setScreen function will be called. 

ever() function is a perfect function for your auth controller.

Workers are only called when you actually change a variable (except the first time), this means that if you have a variable 3, and send a 3 again, worker will not be triggered, the state in the view (Obx / GetX) will refuse the status update, and nothing will be rebuilt, to avoid unnecessary rebuilds altogether.

Getx Get.back()

If you navigate and try to go back to previous page using Get.back(), sometimes this may cause unexpected issues if you are trying to see an updated value.

With Get.back(), you might not see the updated list, map or any other variables. 

Then instead of Get.back(), try to use Get.toNamed()

Recent posts