Home > Software design >  Flutter access a variable from another dart file
Flutter access a variable from another dart file

Time:03-13

I have one dart file called 'BarcodePage.dart' which reads a barcode, the resulting number is stored as the variable 'barcodeResult'. I want to reference this variable in my 'testPage.dart' file as this will be used to search an API for the matching foods data.

How do I go about calling the barcodeResult variable from the BarcodePage file and using it in my testPage file? I'll be concatenating the barcodeResult variable with the baseURL variable & jsonEnd variable to form a completed http address. So that the final http address would read "https://world.openfoodfacts.org/api/v0/product/BARCODERESULT.json"

Thank you!

BarcodePage.dart File:

class _BarcodePageState extends State<BarcodePage> {
  String result= "Scan an item!";

  Future _scanBarcode() async{
    try{
      ScanResult scanResult = await BarcodeScanner.scan();
      String barcodeResult = scanResult.rawContent;
      setState(() {
        result = barcodeResult;
      });

testPage.dart File:

class _testPageState extends State<testPage> {
String baseURL= "https://world.openfoodfacts.org/api/v0/product/";
String jsonEnd = ".json";
String recipeURL= "";

List? listResponse;
Map? mapResponse;
List? listOfResults;
String? itemResult;

  void join(){
    setState(() {
     recipeURL = baseURL   barcodeResult   jsonEnd ;
    });
  }

Future fetchData() async {
  http.Response response;
  response = await http 
  .get(Uri.parse(recipeURL));
  if (response.statusCode == 200) {
    setState(() {
      mapResponse = json.decode(response.body);
      itemResult= mapResponse!['product']['product_name'].toString();
    });
  }
}

CodePudding user response:

Two possibilities to share variable values between different screens is to:

  1. Pass the value from the previous screen to nextScreen in Navigation as Parameter like,

     Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => TestScreen(barcodeResult:barCodeResult),
      ),
    
    
     class TestScreen extends StatelessWidget {
     String? barCodeResult;
     TestScreen({this.barCodeResult});
     @override
     Widget build(BuildContext context) {
     return Container();
     }
      }
    

For more detail visit: https://docs.flutter.dev/cookbook/navigation/passing-data

  1. Or you have to declare the variable globally in some other class and update and use the variable using the Provider package

For more detail visit: https://pub.dev/packages/provider

CodePudding user response:

I'm writing my answer assuming you don't have a proper state management in your app yet otherwise this is not even a problem.

If BarcodePage is first and TestPage is second then you can go with @navidanchitrali 's answer but if it is the opposite, I'd like to suggest you to use the ValueChanged feature of Flutter.

What ValueChange does is you can update your string variable present in your previous screen on the next screen on which you currently are.

Here, we have a barcodeResult variable that needs to be updated with the value we get in the next screen after the scan so here is my proposed code for the same.

This is the Testpage where we pass a valuechange function to Barcode screen

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  String recipeUrl = "No recipe url detected";
  String barcodeResult = "Scan an item!";

  String baseUrl = "https://";
  String jsonEnd = "/pizza";
  void join() {
    setState(() {
      recipeUrl = baseUrl   barcodeResult   jsonEnd;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: MediaQuery.of(context).size.width,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(recipeUrl),
            const SizedBox(height: 40),
            ElevatedButton(
              child: const Text("Scan Code"),
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (ctx) => BarcodePage(
                      result: (url) {
                        setState(() {
                          barcodeResult = url;
                          join();
                        });
                      },
                    ),
                  ),
                );
              },
            )
          ],
        ),
      ),
    );
  }
}

and here is the Barcode page where we have a function which updates the value for the barcoderesult variable.

class BarcodePage extends StatefulWidget {
BarcodePage({Key? key, required this.result}) : super(key: key);
  ValueChanged<String> result;
  @override
  State<BarcodePage> createState() => _BarcodePageState();
}

class _BarcodePageState extends State<BarcodePage> {
  Future _scanBarcode() async {
    try {
      // ScanResult scanResult = await BarcodeScanner.scan();
      // String barcodeResult = scanResult.rawContent;
      setState(() {
        widget.result("barcodeResult");
      });
    } catch (e) {}
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Scan Bar Code")),
      body: Center(
          child: ElevatedButton(
        child: const Text("Scan Code"),
        onPressed: () {
          _scanBarcode();
        },
      )),
    );
  }
}
  • Related