Im having problems receiving data from the api, i a class and a function and a class to use the data but im getting null, i used the function from a class to the other in a FutureBuilder. When i get to the screen where the data is trying to be fetched im just getting the circular progress indicator and in the debug is saying Null is not a subtype of String, i tried looking for the problem but i couldn't fix it, the problem might be when im trying to use the function to the other class in the other file, any help would be much appreciated, if someone could implement his answer on the code i send it would be even more helpful.
class LoginData {
final String loginPhoneNumber;
final String loginPassword;
LoginData({
required this.loginPhoneNumber,
required this.loginPassword,
});
factory LoginData.fromJson(Map<String, dynamic> json) {
return LoginData(
loginPhoneNumber: json['phoneNumber'],
loginPassword: json['lastName']
);
}
}
// function
buildSwipeButton() {
return MenuPage(
sendData: fetchLoginData(),
);
}
Future<List<LoginData>> fetchLoginData() async {
var url = 'https://dev.api.wurk.skyver.co/api/employees';
String basicAuth = 'Basic ' +
base64Encode(
utf8.encode('${emailController.text}:${passwordController.text}'),
);
var response = await http.get(
Uri.parse(url),
headers: <String, String>{'authorization': basicAuth},
);
print(response.body);
if (response.statusCode == 200) {
print(response.statusCode);
List data1 = json.decode(utf8.decode(response.bodyBytes));
return data1.map((data) => LoginData.fromJson(data)).toList();
} else {
throw Exception('Failed to load LoginData');
}
}
// the other class that im trying to use the data from
class MenuPage extends StatefulWidget {
const MenuPage({Key? key, Future<List<LoginData>>? sendData, Future<List<LoginData>>? sendData2}) : super(key: key);
#override _MenuPageState createState() => _MenuPageState();
}
class _MenuPageState extends State<MenuPage> {
final _advancedDrawerController = AdvancedDrawerController();
void _handleMenuButtonPressed() {
_advancedDrawerController.showDrawer();
}
late LoginData data;
Future<LoginData>? sendData;
body: FutureBuilder<LoginData>(
future: sendData,
builder: (context, snapshot) {
if (snapshot.hasData) {
LoginData? data1 = snapshot.data;
data = data1!;
//print(data.loginPhoneNumber);
return afterLoginBody();
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return Center(child: const CircularProgressIndicator());
},
),
afterLoginBody() {
return ListView.builder(
itemCount: data.loginPhoneNumber.length,
itemBuilder: (context, index){
return ListTile(
title: Text(''),
);
});
}
}
Though your question was not completely clear as what data type you are expecting from the api. I've tried to make the future builder running on your code and now you can intrepret the response you receive from the server as your needs.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class LoginData {
final String loginPhoneNumber;
final String loginPassword;
LoginData({
required this.loginPhoneNumber,
required this.loginPassword,
});
factory LoginData.fromJson(Map<String, dynamic> json) {
return LoginData(
loginPhoneNumber: json['phoneNumber'], loginPassword: json['lastName']);
}
}
// function
buildSwipeButton() {
return MenuPage(
sendData: fetchLoginData(),
);
}
Future<List<LoginData>> fetchLoginData() async {
var url = 'https://dev.api.wurk.skyver.co/api/employees';
String basicAuth = 'Basic ' +
base64Encode(
utf8.encode('${emailController.text}:${passwordController.text}'),
);
var response = await http.get(
Uri.parse(url),
headers: <String, String>{'authorization': basicAuth},
);
// List<Map<String,dynamic>> _dummyResponse = [
// {
// "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c3",
// "firstName": "Dibran",
// "lastName": "Krasniqi",
// "phoneNumber": "049000000",
// "idNumber": 1564654
// },
// {
// "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506c5",
// "firstName": "John",
// "lastName": "Doe",
// "phoneNumber": "049123456",
// "idNumber": 65412984
// },
// {
// "id": "0e9ca1b9-6ef3-4e16-93e0-3b4c6c1506e4",
// "firstName": "Ajan",
// "lastName": "Bikliqi",
// "phoneNumber": "049105221",
// "idNumber": 456123
// }
// ];
print(response.body);
if (response.statusCode == 200) {
print(response.statusCode);
List data1 = json.decode(utf8.decode(response.bodyBytes));
return data1.map((data) => LoginData.fromJson(data)).toList();
} else {
throw Exception('Failed to load LoginData');
}
}
// the other class that im trying to use the data from
class MenuPage extends StatefulWidget {
MenuPage({
Key? key,
this.sendData,
this.sendData2,
}) : super(key: key);
Future<List<LoginData>>? sendData;
Future<List<LoginData>>? sendData2;
#override
_MenuPageState createState() => _MenuPageState();
}
class _MenuPageState extends State<MenuPage> {
// final _advancedDrawerController = AdvancedDrawerController();
// void _handleMenuButtonPressed() {
// _advancedDrawerController.showDrawer();
// }
late List<LoginData> data;
Future<LoginData>? sendData;
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<LoginData>>(
future: widget.sendData!,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data != null) {
data = snapshot.data!;
} else {
data = [];
}
//print(data.loginPhoneNumber);
return afterLoginBody();
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return Center(child: const CircularProgressIndicator());
},
),
);
}
afterLoginBody() {
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index].loginPhoneNumber),
);
});
}
}
Related
I want to get data from API and I tried the link in postman and its working here it is: [ { "Id": "14", "title": "Facebook vs instagram?", }, { "Id": "15", "title": "Facebook vs instagram?", }, { "Id": "16", "title": "Facebook vs instagram?", }, ]
but when I am trying to do a map this error appears : error catch type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List' in type cast.
Here is my code : This error appears in this file and print(recieved) print the same data as postman but the problem in map httpservice.dart:
`
class HttpService {
final String postsURL =
"";
Future<List<Post>> getPosts() async {
var request = http.MultipartRequest("POST", Uri.parse(postsURL));
request.headers.addAll(headers);
List<Post> Posts = [];
try {
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
var response = await http.Response.fromStream(streamedResponse);
final result = jsonDecode(response.body) as List;
List<Post> posts = result
.map(
(dynamic item) => Post.fromJson(item),
)
.toList();
return Posts;
}
}
`
post_model.dart :
`
class Post {
final String Id;
final String title;
Post({
required this.Id,
required this.title,
});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
Id: json['Id'] as String,
title: json['title'] as String,
);
}
}
` post.dart :
class PostsPage extends StatelessWidget {
final HttpService httpService = HttpService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Posts"),
),
body: FutureBuilder(
future: httpService.getPosts(),
builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasData) {
List<Post> posts = snapshot.data!;
return ListView(
children: posts
.map(
(Post post) => ListTile(
title: Text(post.title),
subtitle: Text("${post.Id}"),
),
)
.toList(),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}
The http package gives the data as json in default. You are again trying to decode the decode the response body but the jsonDecode expects string type as parameter.
Simply, all you need to do is remove the jsonDecode
From
final result = jsonDecode(response.body) as List;
to
final result = response.body as Map<String, dynamic>;
I want to display data from api to the text and it is showing blank screen and I think I did anything required, I followed this tutrial https://docs.flutter.dev/cookbook/networking/fetch-data and still it does not work for me. I tried everything,
May you please help me.
My api call below
Future<CarDetails?> signInData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
try {
Response response = await _dio.post('$_baseUrl/api/gateway',
data: {
"ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
"PlatformId": "ios",
"ClientUserId": "AhmedOmar",
"VinNumber": VINumber
},
options: Options(headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token",
}));
print("data");
print(response.data.toString());
print(response.statusCode);
if (response.statusCode == 200) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const ResultsPage(),
),
);
}
else if (response.statusCode == 500) {
// call your refresh token api here and save it in shared preference
print(response.statusCode);
await getToken();
signInData();
}
return CarDetails.fromJson(jsonDecode(response.data.toString()));
} catch (e) {
print(e);
}
My other page where I wanna show the results
class ResultsPage extends StatefulWidget {
const ResultsPage({Key? key}) : super(key: key);
#override
_ResultsPageState createState() => _ResultsPageState();
}
class _ResultsPageState extends State<ResultsPage> {
//List<CarDetails> objectList = [];
late Future<CarDetails?>? objectList;
_APIState? api;
#override
void initState() {
super.initState();
objectList = api?.signInData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//centerTitle: true,
),
body: Center(
child: FutureBuilder<CarDetails?>(
future: objectList,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data?.make??"error");
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
),
));
}
}
My model class
class CarDetails {
String? make;
String? type;
String? model;
int? year;
String? body;
String? driveType;
String? fueType;
CarDetails(
{this.make,
this.type,
this.model,
this.year,
this.body,
this.driveType,
this.fueType});
CarDetails.fromJson(Map<String, dynamic> json) {
make = json['make'];
type = json['type'];
model = json['model'];
year = json['year'];
body = json['body'];
driveType = json['drive_type'];
fueType = json['fue_type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['make'] = this.make;
data['type'] = this.type;
data['model'] = this.model;
data['year'] = this.year;
data['body'] = this.body;
data['drive_type'] = this.driveType;
data['fue_type'] = this.fueType;
return data;
}
}
The problem is you are replacing the widget in your navigator stack when you get success.
Future<CarDetails?> signInData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
try {
Response response = await _dio.post('$_baseUrl/api/gateway',
data: {
"ClientPackageId": "0cdd231a-d7ad-4a68-a934-d373affb5100",
"PlatformId": "ios",
"ClientUserId": "AhmedOmar",
"VinNumber": VINumber
},
options: Options(headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token",
}));
print("data");
print(response.data.toString());
print(response.statusCode);
if (response.statusCode == 200) {
//Get rid of this
//Navigator.of(context).pushReplacement(
// MaterialPageRoute(
// builder: (context) => const ResultsPage(),
// ),
//);
// Return your future here
return CarDetails.fromJson(jsonDecode(response.data.toString()));
}
else if (response.statusCode == 500) {
// call your refresh token api here and save it in shared preference
print(response.statusCode);
await getToken();
signInData();
}
} catch (e) {
print(e);
}
I am a newbie in the world of flutter and GetX package and I am trying to create a simple app using my API and I have only JSON API and a model how to create my controller and response data??
Here is my JSON response data from the API
{
"isSuccess": true,
"datacount": 77,
"data": [
{
"provinceID": 1,
"provinceNameEN": "Bangkok",
"geoID": 2
},
{
"provinceID": 2,
"provinceNameEN": "Samut Prakan",
"geoID": 2
}
],
"error": {
"code": null,
"messageToDeveloper": null,
"messageToUser": null
}
}
And this is my model
// To parse this JSON data, do
//
// final provicesModel = provicesModelFromJson(jsonString);
import 'dart:convert';
ProvicesModel provicesModelFromJson(String str) => ProvicesModel.fromJson(json.decode(str));
String provicesModelToJson(ProvicesModel data) => json.encode(data.toJson());
class ProvicesModel {
ProvicesModel({
this.isSuccess,
this.datacount,
this.data,
this.error,
});
bool isSuccess;
int datacount;
List<Datum> data;
Error error;
factory ProvicesModel.fromJson(Map<String, dynamic> json) => ProvicesModel(
isSuccess: json["isSuccess"],
datacount: json["datacount"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
error: Error.fromJson(json["error"]),
);
Map<String, dynamic> toJson() => {
"isSuccess": isSuccess,
"datacount": datacount,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"error": error.toJson(),
};
}
class Datum {
Datum({
this.provinceId,
this.provinceNameEn,
this.geoId,
});
int provinceId;
String provinceNameEn;
int geoId;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
provinceId: json["provinceID"],
provinceNameEn: json["provinceNameEN"],
geoId: json["geoID"],
);
Map<String, dynamic> toJson() => {
"provinceID": provinceId,
"provinceNameEN": provinceNameEn,
"geoID": geoId,
};
}
class Error {
Error({
this.code,
this.messageToDeveloper,
this.messageToUser,
});
dynamic code;
dynamic messageToDeveloper;
dynamic messageToUser;
factory Error.fromJson(Map<String, dynamic> json) => Error(
code: json["code"],
messageToDeveloper: json["messageToDeveloper"],
messageToUser: json["messageToUser"],
);
Map<String, dynamic> toJson() => {
"code": code,
"messageToDeveloper": messageToDeveloper,
"messageToUser": messageToUser,
};
}
This is my services
import 'package:dio/dio.dart';
class ProvinceService {
var dio = Dio();
Future<dynamic> provinceService() async {
return await dio.get(
'URL');
}
}
This is my Controller
class RegisterController extends GetxController {
var provicesList = <ProvicesModel>[].obs;
void fetchprovices() async {
ProvinceService request = ProvinceService();
request.provinceService().then((value) {
if (value.statusCode == 200) {
for (var item in value.data) {
<<< Have Error _TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable')>>>
provicesList.add(ProvicesModel.fromJson(item));
}
} else {
print('Backend error');
}
}).catchError((onError) {
printError();
});
}
}
This is my page response
class Register extends StatefulWidget {
const Register({Key? key}) : super(key: key);
#override
State<Register> createState() => _RegisterState();
}
class _RegisterState extends State<Register> {
#override
void initState() {
registerController.fetchprovices();
super.initState();
}
final registerController = Get.put(RegisterController());
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(child: GetX<RegisterController>(
builder: (controller) {
return ListView.builder(
itemCount: controller.provicesList.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${controller.provicesList[index].datacount}'),
subtitle: Text(
'${controller.provicesList[index].data[index].provinceNameEn}'),
);
},
);
},
))
],
),
);
}
}
Refer this for more info :-> getx_dio_example
/////
var provicesList = ProvicesModel().obs;
void fetchprovices() async {
ProvinceService request = ProvinceService();
request.provinceService().then((value) {
if (value.statusCode == 200) {
final response = ProvicesModel.fromJson(value.data);
provicesList.value = response;
} else {
print('Backend error');
}
}).catchError((onError) {
printError();
});
}
///
return ListView.builder(
itemCount: controller.provicesList.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${controller.provicesList.datacount}'),
subtitle: Text(
'${controller.provicesList.data[index].provinceNameEn}'),
);
},
);
Here I get this JSON object from the API and I need to add it to a list and return so that I can get it from the snapshot to display the data.But i get the snapshot.data as null.Please help me to solve this issue.
...
{
"Data": [
{
"product_name": "MACC Tea Master Blend 40 Bags",
"img_url": "1605262901.jpg",
"order_no": "1625809545122",
"category": [
{
"category_name": "01 Box (40 Bags)",
"order_no": "1625809545122",
"qty": "1",
"line_total": "1.79"
}
]
}
],
"ID": "200"
}
...
This is the code on how i tried so far.
...
Future<List<OrderDetails>> fetchMyOrderDetails(order_no) async {
var body = jsonEncode({"order_no": order_no});
print("order_no : " + order_no);
http.Response response = await http.post(
Uri.encodeFull(api + "get_order_details_by_orderno.php"), //url
headers: {"Accept": "application/json"},
body: body);
if (response.statusCode == 200) {
Map<String, dynamic> map = json.decode(response.body);
// var map = json.decode(response.body);
print("response.body : " + "${response.body}");
print("map : " + "${map['Data']}");
List<OrderDetails> orderDetailsList;
orderDetailsList = (json.decode(response.body)['Data'] as List)
.map((i) => OrderDetails.fromJson(i))
.toList();
return orderDetailsList;
} else {
// print("Failed to load categories");
throw Exception('Failed to load the Orders');
}
}
class OrderDetails {
final String product_name;
final String img_url;
final String order_no;
final List<Category> category;
OrderDetails({
this.product_name,
this.img_url,
this.order_no,
this.category,
});
factory OrderDetails.fromJson(Map<String, dynamic> json) {
return OrderDetails(
product_name: json['product_name'] as String,
img_url: json['img_url'] as String,
order_no: json['order_no'] as String,
category: json['category'] as List,
);
}
}
class Category {
final String category_name;
final String qty;
final String line_total;
Category({this.category_name, this.qty, this.line_total});
factory Category.fromJson(Map<String, dynamic> json) {
return Category(
category_name: json['category_name'] as String,
qty: json['qty'] as String,
line_total: json['line_total'] as String,
);
}
}
...
From the below code i try to access the data but the snapshot.data get null and the page is loading.
...
child: FutureBuilder<List<OrderDetails>>(
future: fetchMyOrderDetails(order_no),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print("snapshot data : " + "${snapshot.data}");
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return Center(
child: Text(snapshot.data.product_name),
);
}
},
),
...
Please update OrderDetails class.
json['category'] as List is List<dynamic> , not List<Category>
factory OrderDetails.fromJson(Map<String, dynamic> json) {
return OrderDetails(
product_name: json['product_name'] as String,
img_url: json['img_url'] as String,
order_no: json['order_no'] as String,
category: (json['category'] == null)
? null
: (json['category'] as List).map(e => Category.fromJson(e)).toList(),
);
}
Future<List<OrderDetails>> fetchMyOrderDetails(order_no) async {
var body = jsonEncode({"order_no": order_no});
print("order_no : " + order_no);
http.Response response = await http.post(
Uri.encodeFull(api + "get_order_details_by_orderno.php"), //url
headers: {"Accept": "application/json"},
body: body);
if (response.statusCode == 200) {
Map<String, dynamic> map = json.decode(response.body);
print("response.body : " + "${response.body}");
print("map : " + "${map['Data']}");
List<OrderDetails> orderDetailsList;
orderDetailsList = (map['Data'] as List)
.map((i) => OrderDetails.fromJson(i))
.toList();
return orderDetailsList;
} else {
// print("Failed to load categories");
throw Exception('Failed to load the Orders');
}
}
I am trying to parse a nested JSON document in my app. The JSON structure looks like this:
[
{
"id": 1,
"content": [
{
"type": "text",
"value": "This is a Text1"
},
{
"type": "latex",
"value": "\frac00"
},
{
"type": "text",
"value": "This is a Text2"
},
{
"type": "latex",
"value": "\frac00"
},
{
"type": "text",
"value": "This is a Text3"
}
]
},
{
"id": 2,
"content": [
{
"type": "text",
"value": "This is a Text"
}
]
}
]
And here are my model classes:
class Tutorial {
String id;
List<Content> content;
Tutorial({this.id, this.content});
Tutorial.fromJson(Map<String, dynamic> json) {
id = json['id'];
if (json['content'] != null) {
content = new List<Content>();
json['content'].forEach((v) {
content.add(new Content.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
if (this.content != null) {
data['content'] = this.content.map((v) => v.toJson()).toList();
}
return data;
}
}
class Content {
String type;
String value;
Content({this.type, this.value});
Content.fromJson(Map<String, dynamic> json) {
type = json['type'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['type'] = this.type;
data['value'] = this.value;
return data;
}
}
This is how I retrieve that Json and make the response object:
import 'package:Mathzi/pages/courses/models/tutorialModel.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'dart:async' show Future;
import 'dart:convert' as convert;
class TutorialService {
Future<List> fetchTutorial() async {
var response = await rootBundle.loadString('assets/tutorial.json');
final jsonResponse = convert.jsonDecode(response) as List;
return jsonResponse.map((tutorial) => Tutorial.fromJson(tutorial)).toList();
}
}
And here are my Screen Widget tree:
final TutorialService tutorialService = TutorialService();
#override
Widget build(BuildContext context) {
return FutureProvider(
create: (context) => tutorialService.fetchTutorial(),
catchError: (context, error) => print(error.toString()),
child: SizeTransition(
axis: Axis.vertical,
sizeFactor: animation,
child: GestureDetector(
//behavior: HitTestBehavior.opaque,
onTap: onTap,
child: SizedBox(
height: 50.0,
width: MediaQuery.of(context).size.width,
child: TutParagraph()
),
),
),
);
}
And my TutParagraph.dart:
import 'package:Mathzi/pages/courses/models/tutorialModel.dart';
import 'package:catex/catex.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/tutorialModel.dart';
class TutParagraph extends StatelessWidget {
const TutParagraph({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
List<Content> parag = Provider.of<List<Content>>(context);
return (parag == null)
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: parag.length,
itemBuilder: (context, index) {
if (parag[index].type.toString() == "text")
return Text(parag[index].value.toString());
else if (parag[index].type.toString() == "latex")
return CaTeX(parag[index].value.toString());
else
return null;
},
);
}
}
if the type is equal to text I use a Text() widget to display it and if it is latex I use CaTex()
When I run my code it gives me this error message:
Error:
Could not find the correct Provider<List> above this
TutParagraph Widget
To fix, please:
Ensure the Provider<List> is an ancestor to this
TutParagraph Widget * Provide types to Provider<List> *
Provide types to Consumer<List> * Provide types to
Provider.of<List>() * Ensure the correct context is being
used.
The best solution is to try to cast and explicitly tell the type of object the List uses to avoid this sort of problems instead of let it infere it
class TutorialService {
Future<List<Tutorial>> fetchTutorial() async { //Tell the trturn type of the List
var response = await rootBundle.loadString('assets/tutorial.json');
final jsonResponse = convert.jsonDecode(response) as List;
return jsonResponse.map<Tutorial>((tutorial) => Tutorial.fromJson(tutorial)).toList();
//Cast the type in the map method <Tutorial>
}
}
Again in the FutureProvider
FutureProvider<List<Tutorial>>( //perhaps it can infere it correctly now that the return type explicitly says is a List<Tutorial>, but lets add it anyway just in case
create: (context) => tutorialService.fetchTutorial(),
catchError: (context, error) => print(error.toString()),
child: ...
)
And in TutParagraph
class TutParagraph extends StatelessWidget {
const TutParagraph({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
List<Tutorial> tutorial = Provider.of<List<Tutorial>>(context); //it should find the FutureProvider
List<Content> parag = (tutorial?.isEmpty ?? true) ? null : tutorial[0].content; //but this will only give you the list of the first element of the tutorial List
return (parag == null)
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: parag.length,
itemBuilder: (context, index) {
if (parag[index].type.toString() == "text")
return Text(parag[index].value.toString());
else if (parag[index].type.toString() == "latex")
return CaTeX(parag[index].value.toString());
else
return null;
},
);
}
}
Now if you want to retrieve only a List<Content> you should try to change the logic of tutorialService.fetchTutorial() to return only that type of list, because the Provider doesn't know what types are inside of Tutorial and obviously if you have a List<Tutorial> it doesn't know the List<Content> of what index of the list of Tutorial you really want