简体   繁体   中英

Flutter display server data / response from json

I have built a page which reads the json from recipeURL and I wish for it to display the product_name value in the json file. However for some reason my future fetchData () class isn't being read as none of the text in my if else statement is being displayed. Am I missing a simple oversight here?

EDIT: The main dart file is my main screen. This is where my navbar is created. Users are redirected to other pages when they click on the corresponding icon. Im having trouble passing BarcodePage(title:title); as parameters in my main file,26th line, can be found under Class MyAppState extends State<MyApp> {

My main dart file:

import 'package:flutter/material.dart';

import 'pages/BarcodePage.dart';
import 'pages/FoodPage.dart';
import 'pages/RecipePage.dart';
import 'pages/ShoppingPage.dart';


void main() {
  runApp(MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()),);
}

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState(){
    return MyAppState();
  }
}


class MyAppState extends State<MyApp> {
 int _selectedPage =0;
 final _pageOptions= [
    FoodPage(),
    RecipePage(),
    BarcodePage(title: ,),
    ShoppingPage(),
  ];

  

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //title: 'Best B4',
        theme: ThemeData(
         primarySwatch: Colors.teal,),
         debugShowCheckedModeBanner: false,
         home: Scaffold (
           appBar: AppBar(
            title:Text(
              'BestB4',
              style: TextStyle(
                  fontFamily: 'PacificoRegular',
                  fontSize: 30,
              ),
            ),
            backgroundColor: Colors.teal,
            elevation: 20,
            actions: [
              IconButton(
                icon: Icon(Icons.qr_code_2_rounded),
                tooltip: 'Add item',
                onPressed:(){
                   Navigator.push(
                     context, 
                     MaterialPageRoute(builder: (context) => BarcodePage()));
                },
              )
              ],
              //ONPRESSED MENU OPEN
           ),
            body:_pageOptions[_selectedPage],
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              backgroundColor: Colors.teal,
              selectedItemColor: Colors.white,
              unselectedItemColor: Colors.white70,
              iconSize: 40,
              selectedFontSize: 15,
              unselectedFontSize: 15,
              currentIndex:_selectedPage,
              onTap: (int index) {
                setState(() {
                  _selectedPage  = index;
                });
              },
              items: [
                BottomNavigationBarItem(
                  icon:Icon(Icons.restaurant_rounded),
                  label: 'Food',
                  ), //, title:Text('Food')
                BottomNavigationBarItem(
                  icon:Icon(Icons.menu_book_rounded),
                  label:'Recipes',
                  ),//, title:Text('Recipes')
                BottomNavigationBarItem(
                  icon:Icon(Icons.add_outlined),
                  label:'Add',
                  ),//, title:Text('Add')
                 BottomNavigationBarItem(
                  icon:Icon(Icons.shopping_cart_rounded),
                  label:'Shopping',
                  ),//,title:Text('Shopping')
              ],
          ),
      ),
      ); 
  }
}

My BarcodePage dart file:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as p;
import 'package:flutter/services.dart';
import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:http/http.dart';



class BarcodePage extends StatefulWidget{
  const BarcodePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _BarcodePageState createState() => _BarcodePageState();
}

var futuredata = {};

class _BarcodePageState extends State<BarcodePage> {
  int counter=0;
  String result= "";

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

    } on PlatformException catch (ex) {
      if (ex.code == BarcodeScanner.cameraAccessDenied) {
        setState((){
        result = "CAMERA PERMISSION WAS DENIED. \n EDIT THIS IN YOUR SETTINGS";
      });
    }else {
      setState(() {
        result = "404 ERROR UNKNOWN $ex";
      });
    }
  } on FormatException {
    setState(() {
      result = "SCAN AN ITEM";
    });
  } catch (ex){
    setState(() {
        result = "404 ERROR UNKNOWN $ex";
      });
    }
  }
  @override
  void initState() {}

  fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.teal,
        title:Text('Add an item',
        style: TextStyle(
        fontFamily: 'Fredoka',
        fontSize: 25,
        ),
        ),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          FutureBuilder(
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting)
                return Center(
                  child: Container(
                    child: CircularProgressIndicator(),
                    height: 50,
                    width: 50,
                  ),
                );
              else if (snapshot.connectionState == ConnectionState.done)
                return ListTile(
                  title: Text(futuredata["product"]["product_name"].toString()),
                  subtitle: Text("France:" +
                      futuredata["product"]["product_name_en"].toString()),
                );
              else {
                return Container(
                  child: CircularProgressIndicator(),
                  height: 50,
                  width: 50,
                );
              }
            },
            future: fetchmydata(),
          )
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        backgroundColor: Color.fromRGBO(51, 171, 160, 100),
        icon: Icon(Icons.camera_alt),
        label: Text("Scan"),
        onPressed: _scanBarcode,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

The Json file looks like this:

JSON LINK: https://world.openfoodfacts.org/api/v0/product/5060391623139.json

在此处输入图像描述

在此处输入图像描述

You can read your json like this

var futuredata = {};
var productname=    futuredata["product"]["product_name"]

Your fetch method like this

 fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

With model Class SampleModel? Mymodel = null; fetchmydata() async { var request = p.Request( 'GET', Uri.parse( 'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
      Mymodel = SampleModel.fromJson(futuredata);
    } else {
      print(response.reasonPhrase);
    }
  }
  1. in the method we first read data from json as string or text
  2. then we decode the string type or text from server to map type

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

SampleCode Dartpad live code check

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:http/http.dart' as p;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

var futuredata = {};

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  void initState() {}

  fetchmydata() async {
    var request = p.Request(
        'GET',
        Uri.parse(
            'https://world.openfoodfacts.org/api/v0/product/5060391623139.json'));

    StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      // print(await response.stream.bytesToString());
      var data = await response.stream.bytesToString();
      futuredata = json.decode(data);
    } else {
      print(response.reasonPhrase);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          FutureBuilder(
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting)
                return Center(
                  child: Container(
                    child: CircularProgressIndicator(),
                    height: 50,
                    width: 50,
                  ),
                );
              else if (snapshot.connectionState == ConnectionState.done)
                return ListTile(
                  title: Text(futuredata["product"]["product_name"].toString()),
                  subtitle: Text("France:" +
                      futuredata["product"]["product_name_en"].toString()),
                );
              else {
                return Container(
                  child: CircularProgressIndicator(),
                  height: 50,
                  width: 50,
                );
              }
            },
            future: fetchmydata(),
          )
        ],
      ),
    );
  }
}

Sample ModelClass

///
/// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/
///
class SampleModelProduct {
/*
{
  "_id": "5060391623139",
  "_keywords": [
    "peanut"
  ],
  "product_name": "Peanut butter",
  "product_name_en": "Peanut butter",
  "product_name_fr": "Peanut butter"
}
*/

  String? Id;
  List<String?>? Keywords;
  String? productName;
  String? productNameEn;
  String? productNameFr;

  SampleModelProduct({
    this.Id,
    this.Keywords,
    this.productName,
    this.productNameEn,
    this.productNameFr,
  });

  SampleModelProduct.fromJson(Map<String, dynamic> json) {
    Id = json['_id']?.toString();
    if (json['_keywords'] != null) {
      final v = json['_keywords'];
      final arr0 = <String>[];
      v.forEach((v) {
        arr0.add(v.toString());
      });
      Keywords = arr0;
    }
    productName = json['product_name']?.toString();
    productNameEn = json['product_name_en']?.toString();
    productNameFr = json['product_name_fr']?.toString();
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['_id'] = Id;
    if (Keywords != null) {
      final v = Keywords;
      final arr0 = [];
      v!.forEach((v) {
        arr0.add(v);
      });
      data['_keywords'] = arr0;
    }
    data['product_name'] = productName;
    data['product_name_en'] = productNameEn;
    data['product_name_fr'] = productNameFr;
    return data;
  }
}

class SampleModel {
/*
{
  "code": "5060391623139",
  "product": {
    "_id": "5060391623139",
    "_keywords": [
      "peanut"
    ],
    "product_name": "Peanut butter",
    "product_name_en": "Peanut butter",
    "product_name_fr": "Peanut butter"
  },
  "status": 1,
  "status_verbose": "product found"
}
*/

  String? code;
  SampleModelProduct? product;
  int? status;
  String? statusVerbose;

  SampleModel({
    this.code,
    this.product,
    this.status,
    this.statusVerbose,
  });

  SampleModel.fromJson(Map<String, dynamic> json) {
    code = json['code']?.toString();
    product = (json['product'] != null)
        ? SampleModelProduct.fromJson(json['product'])
        : null;
    status = json['status']?.toInt();
    statusVerbose = json['status_verbose']?.toString();
  }

  Map<String, dynamic> toJson() {
    final data = <String, dynamic>{};
    data['code'] = code;
    if (product != null) {
      data['product'] = product!.toJson();
    }
    data['status'] = status;
    data['status_verbose'] = statusVerbose;
    return data;
  }
}

try creating agdart file using flutter packages pub run build_runner build. flutter automatically will create your binding class factory. once you have the binding classes created flutter will automatically code your binding class, including nested classes. I personally think automation is the way to handle all interactions with json from the server. The reason you want to use the future.g.dart code generator is to reduce the possibility of error and incorrect type casting.

file.dart
factory ProductView.fromJson(Map<String, dynamic> json) =>
      _$ProductFromJson(json);
Map<String, dynamic> toJson() => _$ProductViewToJson(this);

file.g.dart


ProductView _$ProductViewFromJson(Map<String, dynamic> json) {
  return
ProductView(
    json['field1'] as int,
    json['field2'] as String,
    json['field3'] == null
        ? null
        : DateTime.parse(json['field3'] as String),
  );
}

Map<String, dynamic> _$ProjectViewToJson(ProductView instance) =>
    <String, dynamic>{
      'field1': instance.field1,
      'field2': instance.field2,
      'field3': instance.field3?.toIso8601String(),
    };

decoding the json

 var client = http.Client();
      Map<String, String> headers = new HashMap();
      headers['Accept'] = 'application/json';
      headers['Content-Type'] = 'application/json';
      headers['Authorization'] = 'Bearer $token';
var response = await client.get(url, headers: headers).timeout(_TIMEOUT);
    var parsed = json.decode(response.body);
    var view = ProductView.fromJson(parsed);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM