Home > Net >  Flutter JSON decoding
Flutter JSON decoding

Time:12-15

I got a website with generated JSON which Flutter reads. JSON contains a list of names which I would want to display as list in column. When launching app it shows in the center:

FormatException: SyntaxError: Unexpected token < in JSON at position 0

I've made sure to check if JSON is invalid, but there is no problems with it.

    {
    "data": [
        {
            "Name": "PlayerOne",
            "Data": "{\"isOnline\":false}"
        },
        {
            "Name": "PlayerTwo",
            "Data": "{\"isOnline\":false}"
        }
    ]
}

It's supposed to all of the names if isOnline is set to true. Here is the factory function for decoding JSON:

    factory PlayersOnline.fromJson(Map<String, dynamic> json) {
    return PlayersOnline(
        Name: json["data.Name"],
        isOnline: json["data.Data"]
    );

and the future builder from build:

    @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Test"),
        ),
        body: FutureBuilder(
          future: fetchOnline(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data!);
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

            return const CircularProgressIndicator();
          },
        )
      ),
    );


  }

Method for requesting:

Future<PlayersOnline> fetchOnline() async {

  final response = await http.get(Uri.parse("serwer.fabrykacraft.pl"));

  if (response.statusCode == 200) {


    return PlayersOnline.fromJson(json.decode(response.body));
  } else {
    throw Exception("Can't fetch data");

  }

}

Though JSON is formatted from MySQL via PHP.

Edit: There was also a problem with fetching json because I forgot about the header in php code.

CodePudding user response:

class PlayersOnline {
  List<Data> data;

  PlayersOnline({this.data});

  PlayersOnline.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = new List<Data>();
      json['data'].forEach((v) {
        data.add(new Data.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Data {
  String name;
  String data;

  Data({this.name, this.data});

  Data.fromJson(Map<String, dynamic> json) {
    name = json['Name'];
    data = json['Data'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['Name'] = this.name;
    data['Data'] = this.data;
    return data;
  }
}

I used this website https://jsontodart.com/ to generate response model.

CodePudding user response:

Check out the below code

void main() {
  var data =     {
    "data": [
        {
            "Name": "PlayerOne",
            "Data": "{\"isOnline\":false}"
        },
        {
            "Name": "PlayerTwo",
            "Data": "{\"isOnline\":false}"
        }
    ]
};
  PlayersOnline player = PlayersOnline.fromJson(data);
  
  print(player.data?.first.name); // PlayerOne
}

class PlayersOnline {
  List<Data>? data;

  PlayersOnline({this.data});

  PlayersOnline.fromJson(Map<String, dynamic> json){
    data = List.from(json['data']).map((e)=>Data.fromJson(e)).toList();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data?.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Data {
  String? name;
  String? data;

  Data({this.name, this.data});

  Data.fromJson(Map<String, dynamic> json) {
    name = json['Name'];
    data = json['Data'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['Name'] = this.name;
    data['Data'] = this.data;
    return data;
  }
}


Future builder part

FutureBuilder<PlayersOnline>(
          future: fetchOnline(),
          builder: (BuildContext context, AsyncSnapshot<PlayersOnline> snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data?.first?.name);
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

            return const CircularProgressIndicator();
          },
        )

Link: https://dartpad.dartlang.org/f8c6d477dcbf426a6b5e1bd2fc30bb41

  • Related