Search code examples
flutterdartmobilebarcode-scanner

The function setState is not defined


I am trying to make a barcode scanner inside my mobile app. I made a file that's called barcode_scanner.dart and one called barcode_scanner_bloc.dart. I am trying to write scan() method inside the barcode_scanner_bloc.dart and call it from barcode_scanner.dart. For that I did this:

import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:flutter/material.dart';

import 'barcode_scanner_bloc.dart';

class ScanBarcode extends StatefulWidget {
  @override
  _ScanBarcodeState createState() => _ScanBarcodeState();

  static scan() {}
}

class _ScanBarcodeState extends State<ScanBarcode> {
  String barcode = "";
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: new Text('Code Scanner'),
        centerTitle: true,
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
              child: RaisedButton(
                color: Colors.purple,
                textColor: Colors.white,
                splashColor: Colors.blueGrey,
                onPressed: scan,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Icon(Icons.scanner, size: 40),
                    SizedBox(width: 10),
                    Column(
                      children: <Widget>[
                        Text('Camera Scan'),
                        SizedBox(
                          height: 2,
                        ),
                        Text('Click here')
                      ],
                    )
                  ],
                ),
              ),
            ),
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
              child: Text(
                barcode,
                textAlign: TextAlign.center,
              ),
            )
            
          ],
          
        ),
      ),
    );
  }
}

And now I am trying to add the scan() method, but when I try to do that in another file, it gives the error. Here is my code:

import 'dart:async';
import 'package:barcode_scan/barcode_scan.dart';
import 'package:flutter/material.dart';

import 'barcode_scanner.dart';




Future scan() async {
  try {
    String barcode = await ScanBarcode.scan();
    setState(() {
      this.barcode = barcode;
    });
  } on PlatformException catch (e) {
    if (e.code == ScanBarcode.CameraAccessDenied) {
      setState(() {
        this.barcode = 'camera permission not granted';
      });
    } else {
      setState(() {
        this.barcode = 'Unknown error: $e';
      });
    }
  } on FormatException {
    setState(() {
      this.barcode = 'null (user returned using the back button)';
    });
  } catch (e) {
    setState(() {
      this.barcode = 'Unknown error: $e';
    });
  }
}

If someone could help me I would be really happy.


Solution

  • you can't access setState from outside the StatefulWidget

    try making your scan() function with in the StatefulWidget class

    or try to make the scan() function return the value of barcode then call setState

    so it would be like

    Future<String> scan() async {
      try {
        String barcode = await ScanBarcode.scan();
        return barcode;
      } on PlatformException catch (e) {
        if (e.code == ScanBarcode.CameraAccessDenied) {
            return 'camera permission not granted';
        } else {
           return 'Unknown error: $e';
        }
      } on FormatException {
        return  'null (user returned using the back button)';
      } catch (e) {
         return  'Unknown error: $e';
      }
    }
    

    and in your ScanBarcode class

    onPressed: () async {
    setState(() {
            this.barcode = await scan();
          });
    },