user1080247
user1080247

Reputation: 1166

why flutter getx package navigation show missing controller?

I have two Pages , settings page and login page which is binding with their controllers as getx documentation said , and I use GetMatrial() widget to wrap the the app tree , but when i use Get.to() to into the settings page to go to the Login Page , it display this error , although I make a file binding and add the user controller correctly in bindings file .

AS Side note : the state management works correctly with no issue , the only issue with navigation

   > ======== Exception caught by widgets library ======================================================= The following message was thrown building LoginPage(dirty): "UserController" not
    > found. You need to call "Get.put(UserController())" or
    > "Get.lazyPut(()=>UserController())"
    > 
    > The relevant error-causing widget was:    LoginPage
    > file:///D:/projects/talab/lib/modules/settings/views/settings_page.dart:141:42
    > When the exception was thrown, this was the stack: 
    > #0      GetInstance.find (package:get/get_instance/src/get_instance.dart:332:7)
    > #1      GetView.controller (package:get/get_state_manager/src/simple/get_view.dart:38:37)
    > #2      LoginPage.build (package:talab/modules/users/views/login_page.dart:33:26)
    > #3      StatelessElement.build (package:flutter/src/widgets/framework.dart:4569:28)
    > #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15) 
    

the settings controller
   import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart' as lng;
import 'package:talab/helpers/constant_helper.dart';
import 'package:talab/modules/settings/controllers/settings_controller.dart';
import 'package:talab/modules/users/views/login_page.dart';


    class SettingsPage extends GetView<SettingsController> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body:  Column(
            children: [
              Image(image: AssetImage("assets/images/logo.png"),height: 100,width: 200,),
              SizedBox(height: 10,),
              FormBuilder(
                // context,
                  key: controller.settingKey,
                  // autovalidate: true,
                  child: Column(
                    children: <Widget>[
    
                      _buildNavigationButton("logout",Icons.logout),
                    ],
                  )
              ),
            ],
          ),
        );
      }
    
    
      Row _buildNavigationButton(text,btnIcon) {
        return   Row(
          children: [
            Padding(
              padding:EdgeInsets.all(8.0),
              child: Icon(btnIcon, color: AppColors.buttonBackgroundColor),
            ),
            Padding(
              padding:EdgeInsets.all(15.0),
              child:GestureDetector(
                  onTap: ()=> Get.to(() => LoginPage()),
                  child: Text(text,style: AppStyles.primaryMediumTextStyle)
              ),
            )
          ],
        );
      }
    
    }



the binding helper class

    import 'package:talab/modules/home/controllers/home_controller.dart';
    import 'package:talab/modules/settings/controllers/settings_controller.dart';
    import 'package:talab/modules/todo/controllers/todo_form_controller.dart';
    import 'package:talab/modules/todo/controllers/todo_list_controller.dart';
    import 'package:talab/modules/users/controllers/user_controller.dart';
    import 'package:talab/modules/home/views/home_page.dart';
    import 'package:get/get.dart';
    import 'package:talab/modules/settings/views/settings_page.dart';
    import 'package:talab/modules/todo/views/add_todo_page.dart';
    import 'package:talab/modules/todo/views/edit_todo_page.dart';
    import 'package:talab/modules/todo/views/todo_list_page.dart';
    import 'package:talab/modules/users/views/login_page.dart';
    import 'package:talab/modules/users/views/register_page.dart';
    import 'constant_helper.dart';
    
    class AppPages {
      static const INITIAL = AppRoutes.RootURL;
    
      static final routes = [
        //Simple GetPage
        GetPage(
          name: AppRoutes.HomePageURL,
          page: () => HomePage(),
          binding: BindingsBuilder(() {
            Get.lazyPut<HomeController>(() => HomeController());
           // Get.put<Service>(()=> Api());
          }),
          transition: Transition.fade,
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.LoginPageURL,
          page: () => LoginPage(),
          binding: BindingsBuilder(() => Get.put(UserController())),
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.RegisterPageURL,
          page: () => RegisterPage(),
          binding: BindingsBuilder(()=>Get.put(UserController())),
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.SettingPageURL,
          page: () => SettingsPage(),
          binding: BindingsBuilder(() {
            Get.lazyPut<SettingsController>(() => SettingsController());
            // Get.put<Service>(()=> Api());
          }),
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.TodoListPageURL,
          page: () => TodoListPage(),
          binding: BindingsBuilder(() {
            Get.lazyPut<TodoListController>(() => TodoListController());
            // Get.put<Service>(()=> Api());
          }),
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.EditTodoPageUrl,
          page: () => EditTodoPage(),
          binding: BindingsBuilder(() {
            Get.lazyPut<TodoFormController>(() => TodoFormController());
            // Get.put<Service>(()=> Api());
          }),
          parameter: {},
          middlewares: [],
          children: [],
        ),
        GetPage(
          name: AppRoutes.AddTodoPageURL,
          page: () => AddTodoPage(),
          binding: BindingsBuilder(() {
            Get.lazyPut<TodoFormController>(() => TodoFormController());
            // Get.put<Service>(()=> Api());
          }),
          parameter: {},
          middlewares: [],
          children: [],
        ),
      ];
    }



my app widget

    class MyApp extends StatelessWidget {
    
      const MyApp();
    
      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          initialBinding: BindingsBuilder(() {
            Get.lazyPut<SettingsController>(() => SettingsController());
            // Get.put<Service>(()=> Api());
          }),
          home: SettingsPage(), //RegisterPage(),
          enableLog: true,
          debugShowCheckedModeBanner: false,
          title: Config.AppName,
          theme: AppThemes.appTheme,
          locale: LocalizationService.locale,
          fallbackLocale: LocalizationService.fallbackLocale,
          translations: LocalizationService(),
          initialRoute: AppPages.INITIAL,
          getPages: AppPages.routes,
        );
      }
    /*LoginPage(),*/
    }

Upvotes: 2

Views: 5266

Answers (2)

Shailendra Rajput
Shailendra Rajput

Reputation: 2879

You can also define controller in your View file like this.

  final profileController = Get.put(StudioProfileController());

Upvotes: 1

S. M. JAHANGIR
S. M. JAHANGIR

Reputation: 5020

You are binding the controller on named route but using un named route. So instead of using onTap: ()=> Get.to(() => LoginPage()), use: onTap: ()=> Get.toNamed(AppRoutes.LoginPageURL),

Update

If you want to use unnamed routes, then you need to extend/implement the Bindings class like:

class LoginBinding extends Bindings{
     void dependencies(){
       Get.lazyPut(()=> LoginController());
    }
 }

Then you can use it like: Get.to(()=> LoginPage(), binding: LoginBinding());

Upvotes: 5

Related Questions