Reputation: 1197
I have a .net server web api call that I am trying to port the client part to Flutter from Xamarin. mostly impressed with flutter/Dart except the json serialization/deserialization is a pain! my api returns a list of exercise routines that have embedded list of machines. this is pretty simp and normal stuff. my generated JSON looks like :
[
{"id":1,"
Name":"back",
"userid":1,
"cloned":0,
"Machines":
[
{"machineid":2,
"Name":"Leg Extension","PictureUrl":"https://l},
{"machineid":3,"Name":"yoga ball","PictureUrl":"https://
}
I originally tried the manual approach with dart.convert and things worked for my serializing a list of routines. however then I decided to use the code generation as described here my code thru following exception when I called jsonDecode:
type 'List' is not a subtype of type 'Map'
my flutter UI code looks like:
_fetchData() async {
setState(() {
isLoading = true;
});
final response =
await http.get("http://fitnesspal.azurewebsites.net/api/routines");
if (response.statusCode == 200) {
// list = (json.decode(response.body) as List)
// .map((data) => new Routine.fromJson(data))
// .toList();
// final jsonResponse = json.decode(response.body);
try {
String json1 = response.body;
Map map1 = jsonDecode(json1);
var test = Routine.fromJson(map1);
}
catch (e) {
print(e.toString());
}
setState(() {
isLoading = false;
});
} else {
throw Exception('Failed to load photos');
}
}
import 'package:json_annotation/json_annotation.dart';
import 'package:fitnesspal/Models/Machine.dart';
part 'Routine.g.dart';
@JsonSerializable(nullable: false)
class Routine{
final int id;
final String name;
@JsonKey(name: 'Machines')
List<Machine> Machines;
Routine({this.id,this.name,this.Machines});
factory Routine.fromJson(Map<String, dynamic> json) =>
_$RoutineFromJson(json);
Map<String, dynamic> toJson() => _$RoutineToJson(this);
}
I followed the described code generation steps
Upvotes: 1
Views: 2407
Reputation: 1197
sorry the above was DFU error with stackoverflow. your idea worked but to get the list of routines that I wanted I ended up with:
list = (jsonDecode(response.body) as List)
.map((data) => new Routine.fromJson(data))
.toList();
I then use the routine name in my listBuilder and looks good so feeling pretty good but then I need to pass the embedded machine list to my list of machines widget. so I add a stateful widget called MachineList as follows: notice I setup my constructor to accept the List
class MachineList extends StatefulWidget {
final List<Machine> machines;
MachineList({Key key, this.machines}) : super(key: key);
@override
_MachineListState createState() => _MachineListState(machines);
}
then back in main.dart I want to navigate in the list item ontap :
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MachineList(
machines: list[index].machines)
)
);
lib/main.dart:122:82: Error: The argument type 'dart.core::List<#lib1::Machine>' can't be assigned to the parameter type 'dart.core::List<#lib2::Machine>
OMG where is it getting lib2 from
**** found my issue a case mismatch on the import In Dart, two libraries are the same if, and only if, they are imported using the same URI. If two different URIs are used, I had .../Models/. and ../models painful learning experience as did not realize Dart was so sensitive as to used to c#
Upvotes: 0
Reputation: 103401
This doesn't work because json1 is a List
of objects, not a Map.
Map map1 = jsonDecode(json1);
Try using this :
List list = jsonDecode(json1);
And get the first element just for testing (in a real scenario you will have to loop the list)
var test = Routine.fromJson(list[0]);
Upvotes: 1