Trying to get data from the api and when i try to use that data, im getting the snapshot.hasError. The snapShot.hasError is Null is not a subtype of type 'String', Not sure where the problem is, so any help would be appreciative, Here are the two files witch im working with and the data that i get from the api
dataset_forKuiz.dart
Future<List<KuizData>?> fetchData2() async {
String username = 'hello';
String password = 'hello';
String basicAuth = base64Encode(utf8.encode('$username:$password'));
print("BASOICCCCCCCCPPPPP $basicAuth");
var url = "https://fm-srvc.herokuapp.com/api/order-words";
var response = await http.get(
Uri.parse(url),
headers: {
HttpHeaders.authorizationHeader: 'Basic $basicAuth',
},
);
print("Hellooo ${response.statusCode}");
if (response.statusCode == 200) {
List data2 = json.decode(utf8.decode(response.bodyBytes));
return data2.map((data) => KuizData.fromJson(data)).toList();
} else {
throw Exception('Unexpected error occured');
}
}
class KuizData {
int level;
String question;
List options;
String answer;
int time;
KuizData(
{required this.level,
required this.question,
required this.options,
required this.answer,
required this.time});
factory KuizData.fromJson(Map<String, dynamic> json) {
return KuizData(
level: json['level'],
question: json['question'],
options: json['options'],
answer: json['answer'],
time: json['time']);
}
}
kuizi.dart
class Kuizi extends StatefulWidget {
const Kuizi({Key? key}) : super(key: key);
@override
_KuiziState createState() => _KuiziState();
}
class _KuiziState extends State<Kuizi> {
late Future<List<KuizData>?> futureData2;
void initState() {
super.initState();
futureData2 = fetchData2();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
toolbarHeight: 60,
backgroundColor: Color(0xFF0A869B),
title: Row(children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back),
color: Colors.white,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RenditFjaletScreen()));
}),
Padding(
padding: const EdgeInsets.only(left: 40),
child: Align(
alignment: Alignment.topCenter,
child: Text('Kuizi',
style: GoogleFonts.fredokaOne(
textStyle: TextStyle(fontSize: 30)))))
])),
body: FutureBuilder<List<KuizData>?>(
future: futureData2,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<KuizData>? data = snapshot.data;
data?.sort((a, b) => a.level.compareTo(b.level));
return Stack(children: [
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
'assets/background.PNG',
),
fit: BoxFit.cover)),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: GridView.count(
crossAxisCount: 4,
children: List.generate(data!.length, (index) {
return InkWell(
splashColor: Colors.blue.withAlpha(20),
onTap: () {
},
child: Card(
elevation: 3.0,
margin: EdgeInsets.all(7.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
child: Container(
child: Align(
alignment: Alignment.center,
child: Container(
child: Text(
'${data[index].level}',
style: GoogleFonts.fredokaOne(
textStyle: TextStyle(
fontSize: 30.0.sp,
color: Color(0xFF50CFFD),
))
)
))
)
)
);
})
)
))
]);
} else if (snapshot.hasError) {
return Text("OO ILAZZZ ${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
}));
}
}
Data from api
"id": "1c2ef15c-6dec-4bab-968e-d3a9ab48f897",
"level": 1,
"question": "Cili është urdhri më i rëndësishëm?",
"options": [
"Teuhidi.",
"Namazi.",
"Adhurimi.",
"Agjërimi."
],
"answer": "Teuhidi.",
"time": 65,
"updatedAt": "2020-07-09T06:38:08.222990Z"
},
CodePudding user response:
You expect a list. Your JSON data is just a single data point, not a list. Either fix your data or fix your code.
And while you are at it, Future<List<KuizData>?> fetchData2()
should really be Future<List<KuizData>> fetchData2()
, because you never actually return null. That will save you a lot of ?
and `!´ trouble down the road. Null safety is not easy, don't make it harder than it has to be for yourself.
CodePudding user response:
Your Future function expects a List<KuizData>
but you are only passing single object instead. Do following changes to your dataset_forKuiz.dart
file
//create this function to return List of KuizData
List<KuizData> list(data) => List.from(data).map((e) => KuizData.fromJson(e)).toList();
Future<List<KuizData>?> fetchData2() async {
String username = 'hello';
String password = 'hello';
String basicAuth = base64Encode(utf8.encode('$username:$password'));
print("BASOICCCCCCCCPPPPP $basicAuth");
var url = "https://fm-srvc.herokuapp.com/api/order-words";
var response = await http.get(
Uri.parse(url),
headers: {
HttpHeaders.authorizationHeader: 'Basic $basicAuth',
},
);
print("Hellooo ${response.statusCode}");
if (response.statusCode == 200) {
List data2 = json.decode(utf8.decode(response.bodyBytes));
return list(response.bodyBytes); // this will return a list as expected
} else {
throw Exception('Unexpected error occured');
}
}