FLUTTER: How can I use a variable from the main ( ) function into my Stateless Widget error: Undefined name 'faceCamera'?

63 views Asked by At

I am looking to use the camera package in FLUTTER, I am still relatively new to declarative programming, I was able to create an initialization parameter within the 'main.dart' function as shown below:

Future <void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final cameras = await availableCameras();
  final faceCamera = cameras.first;
  runApp(
    const MyCameraApp(),
  );
}

Then in my stateless widget within the main.dart file (the main page of the app), I created a FloatingActionButton.extended() as shown below:

FloatingActionButton.extended(
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => MyAppCameraPage(cameras: [faceCamera],),
                          ),
                        );
                      },

This might be a novice question, but what am I doing wrong to get the following error?

Undefined name 'faceCamera'

My Question is: how do I pass this value to the camera page where the camera preview will be used? By doing this I am looking to avoid the instantiation error for the camera which doesn't load the camera at app launch and shows the "Camera not loaded" error on my tester device's screen making it fully red and scary looking.

For context, this is what my camera page's Stateful widget instantiation looks like:

class MyAppCameraPage extends StatefulWidget {
  MyAppCameraPage({super.key, required this.cameras});
  final List<CameraDescription> cameras;

  @override
  State<MyAppCameraPage> createState() => _MyAppCameraPageState();
}

All related packages have been imported so no errors there.

Any help, and helpful tips in understanding the declarative-based programming in FLUTTER would be helpful.

I have tried declaring the instantiation variable as a global parameter like the FLUTTER team shows in the package listed here: Camera Package Flutter.

And, I have tried instantiating the cameras in the camera page itself, which obviously didn't work because the camera has to be initialized at the app start -- something I still don't fully understand in declarative coding.

I have also tried creating the camera page widget as Stateless so I will have an easier time importing the camera package and initializing, which, surprise surprise was more difficult to do than I imagined.

What I was expecting was to use the local variable inside the main() function post camera initialization that I declared inside my page route FloatingActionButton and avoid the "Camera uninitialized scary looking error" popping up on my tester device altogether and get a NICE CLEAN CameraPreview. My expectations are to get to the CameraPreview as described in the question.

2

There are 2 answers

1
rasityilmaz On BEST ANSWER

This code example is offered by camera package

BUT I don't suggest that.

// Global Variable
late List<CameraDescription> cameras;

Future <void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  cameras = await availableCameras();
  runApp(
    const MyCameraApp(),
  );
}

class MyAppCameraPage extends StatefulWidget {
  const MyAppCameraPage({super.key});

  @override
  State<MyAppCameraPage> createState() => _MyAppCameraPageState();
}

class _MyAppCameraPageState extends State<MyAppCameraPage> {

  final CameraDescription faceCamera = camera.first;

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

I prefer that =>

class MyAppCameraPage extends StatefulWidget {
  const MyAppCameraPage({super.key});

  @override
  State<MyAppCameraPage> createState() => _MyAppCameraPageState();
}

class _MyAppCameraPageState extends State<MyAppCameraPage> {
  late final CameraDescription? faceCamera;

  Future<void> setAvaibleCamera() async {
    try {
      await availableCameras().then((value) {
        if (value != null && value.isNotEmpty) {
          faceCamera = value.first;
        }
      });
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
1
Ali Jawad On

Two ways you could access that variable faceCamera

  1. Global Variable

just by putting the faceCamera out of the main method (and also the variable above it) would make it pretty globally accessible to all the files in your app. Sometimes, this method is not considered a good practice.

  1. Constructors

Your Application is small enough, so you can create a constructor of myCameraApp and declare a variable that will hold the data of faceCamera which will pass it to the MyCameraAppPage(cameras: [faceCameraFromMyCameraApp])