Home > database >  The return of string value is null or empty when I call the function using GetX in flutter
The return of string value is null or empty when I call the function using GetX in flutter

Time:01-19

I want to call the string function, I use package_info_plus to get the packageName when I run the app, just like this:

class SplashScreenController extends GetxController {
  late String one = '';
  late RxString two = ''.obs;

  @override
  void onInit() {
    _initPackageInfo();
    _setImage();
    Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
    super.onInit();
  }

  @override
  void onClose() {}

  Future<void> _initPackageInfo() async {
    final info = await PackageInfo.fromPlatform();
    one = info.packageName;
  }

  String _setImage() {
    if (one == 'com.package.one') {
      return two.value = Images.one;
    } else if (one == 'com.package.two) {
      return two.value = Images.two;
    } else {
      return two.value = Images.one;
    }
  }
}

And when I try to call RxString two inside Image.asset()

@override
  Widget build(BuildContext context) {
    print(controller.two);
    return Obx(() => Scaffold(
            body: Container(
          color: const Color.fromARGB(255, 255, 255, 255),
          alignment: AlignmentDirectional.center,
          child: controller.one.isNotEmpty
              ? Image.asset(controller.two.toString())
              : const SizedBox.shrink(),
        )));
  }

It show the null value, is there any way for me to use the packageName value in conditional case and then calling it in Image.asset() widget?

CodePudding user response:

I have rewrite your controller and UI Code. Please check it out.

Controller (SplashScreen)

class SplashScreenController extends GetxController {
  late RxString one = ''.obs;
  late RxString two = ''.obs;

  @override
  void onInit() async {
    await _initPackageInfo();
    Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
    super.onInit();
  }

  @override
  void onClose() {}

  Future<void> _initPackageSetImage() async {
    final info = await PackageInfo.fromPlatform();
    one.value = info.packageName;
    switch(one.value){
      case 'com.package.one':
        two.value = Images.one;
        break;
      case 'com.package.two':
        two.value = Images.two;
        break;
      default:
        two.value = Images.one;
        break;
    }
  }
}

UI (SplashScreen)

@override
  Widget build(BuildContext context) {
    
    return Scaffold(
            body: Container(
          color: const Color.fromARGB(255, 255, 255, 255),
          alignment: AlignmentDirectional.center,
          child: Obx((){
             print(controller.two.value);
             if(controller.one.value.isNotEmpty){
               return Image.asset(controller.two.value);
             }
             return const SizedBox.shrink();
           }),
        ));
  }

CodePudding user response:

This is not related really to Getx, it's related to the Dart language programming and futures, here in this piece of code:

  @override
      void onInit() {
        _initPackageInfo();
        _setImage();
        Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
        super.onInit();
      }

_initPackageInfo() is an asynchronous method, which needs time to resolve (so the info variable gets an PackageInfo instance ), this means that executing it synchronously will still get you the instance, but it will not wait for it, and it will run _setImage() immediately which at this point PackageInfo.fromPlatform() did not get resolved yet, so it's null, what you need to do is to make it wait until in have the instance then continues running other code :

 @override
  void onInit() {
    _initPackageInfo().then((val) {
     // this will be executed when _initPackageInfo() finishes.
     _setImage();
    Timer(Duration(seconds: 5), () => Get.offNamed(Routes.DASHBOARD));
   });
  super.onInit();
  }
  • Related