GetMidleware not working on bottomNavigationBar - flutter - GetX

221

BottomNavigationBar (also TabBar) doesn't change routes. It's essentially single page. Therefore route middlewares can't be used with them without complications. Instead, you can use the auth check on the respective controllers of the views of navigation bar items. A very good place is in the onReady method of the GetxControllers.

Share:
221
adian
Author by

adian

Updated on January 03, 2023

Comments

  • adian
    adian over 1 year

    i have problem with GetMidleware, so i have 3 item in bottomNavigationBar:

    1. Home
    2. MyTicket
    3. Profile

    i want user can acces home without login so i put midleware just on myTicket and Profile, but when i click MyTicket or Profile i still can access that and not redirect to login page.

    this is my midleware class :

    class AuthMiddleware extends GetMiddleware {
      final authService = Get.find<AuthService>();
    
      @override
      RouteSettings? redirect(String? route) {
        if (!authService.currentUser.value.isAuthenticated) {
          Get.log(authService.currentUser.value.isAuthenticated.toString());
          return const RouteSettings(name: Routes.LOGIN);
        }
        return null;
      }
    }
    

    this is my appPage class :

    class AppPages {
       
      static const INITIAL = Routes.ROOT;
       static final routes = [
    
          GetPage(
          name: _Paths.ROOT,
          page: () => const RootView(),
          binding: RootBinding(),
        ),
    
          GetPage(
          name: _Paths.HOME,
          page: () => const HomeView(),
          binding: RootBinding(),
        ),
          
          GetPage(
          name: _Paths.MYTICKET,
          page: () => const MyTicketView(),
          binding: RootBinding(),
          middlewares: [AuthMiddleware()],
        ),
    
         GetPage(
          name: _Paths.PROFILE,
          page: () => const ProfileEditView(),
          binding: RootBinding(),
          middlewares: [AuthMiddleware()],
        ),
       ]
    }
    

    this is my root controller:

    class RootController extends GetxController {
      final Rx<String> title = Strings.home.obs;
      final Rx<int> currentIndex = 0.obs;
      final authService = Get.find<AuthService>();
    
      @override
      void onClose() {
        super.dispose();
      }
    
      List<Widget> pages = [
        const HomeView(),
        const MyTicketView(),
        const ProfileView(),
        // const BlankView(),
      ];
    
      //get current page for view
      Widget get currentPage => pages[currentIndex.value];
    
      //change page when bottom nav item is taped
      Future<void> changePage(int _index) async {
        changeTitle(_index);
        if (Get.currentRoute == Routes.ROOT) {
          await changePageInRoot(_index);
        } else {
          await changePageOutRoot(_index);
        }
      }
    
      Future changeTitle(int index) async {
        switch (index) {
          case 0:
            title.value = Strings.home;
            break;
          case 1:
            title.value = Strings.myTicket;
            break;
          case 2:
            title.value = Strings.myProfile;
            break;
          default:
        }
      }
    
      //change page if previously page in root
      Future<void> changePageInRoot(int _index) async {
        currentIndex.value = _index;
        await refreshPage(_index);
      }
    
      //change page if previously page out of root
      Future<void> changePageOutRoot(int _index) async {
        currentIndex.value = _index;
        await refreshPage(_index);
        await Get.offNamedUntil(Routes.ROOT, (Route route) {
          if (route.settings.name == Routes.ROOT) {
            return true;
          }
          return false;
        }, arguments: _index);
      }
    }
    
    //call page by index
    Future<void> refreshPage(int _index) async {
      switch (_index) {
        case 0:
          {
            Get.find<HomeController>().onInit();
            break;
          }
        case 1:
          {
            Get.find<MyTicketController>().onInit();
            break;
          }
        case 2:
          {
            Get.find<ProfileController>().onInit();
            // Get.find<BlankController>().onInit();
            break;
          }
      }
    }
    

    and this is my root view where i put my bottomNavigationBar :

    class RootView extends GetView<RootController> {
      const RootView({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Obx(
          () => Scaffold(
            appBar: PreferredSize(
              preferredSize: const Size.fromHeight(Dimensions.appBarHeight),
              child: BackWidget(title: controller.title.value),
            ),
            backgroundColor: Colors.white,
            bottomNavigationBar: Material(
              elevation: 10,
              // borderRadius: BorderRadius.circular(20),
              child: BottomNavigationBar(
                  selectedIconTheme:
                      const IconThemeData(color: CustomColor.primaryColor),
                  selectedLabelStyle: const TextStyle(fontSize: 15),
                  selectedItemColor: CustomColor.primaryColor,
                  backgroundColor: Colors.white,
                  elevation: 25,
                  type: BottomNavigationBarType.fixed,
                  currentIndex: controller.currentIndex.value,
                  onTap: (index) => controller.changePage(index),
                  items: [
                    bottomNavigationBarItemWidget(
                      'assets/svg/home.svg',
                      Strings.home,
                    ),
                    bottomNavigationBarItemWidget(
                      'assets/svg/document.svg',
                      Strings.myTicket,
                    ),
                    bottomNavigationBarItemWidget(
                      'assets/svg/profile.svg',
                      Strings.myProfile,
                    ),
                  ]),
            ),
            body: controller.currentPage,
          ),
        );
      }
    
      bottomNavigationBarItemWidget(String icon, String label) {
        return BottomNavigationBarItem(
          icon: SvgPicture.asset(
            icon,
            color: Colors.grey,
            height: 24,
            width: 24,
          ),
          activeIcon: SvgPicture.asset(
            icon,
            color: CustomColor.primaryColor,
            height: 24,
            width: 24,
          ),
          label: label,
          tooltip: label,
        );
      }
    }
    
  • adian
    adian over 2 years
    Thank this work for me