I have a function that takes some json and puts the entire object into a dynamic list. I am having trouble looping over that list using the futurebuilder. I always get "the getter 'length' isn't defined for the class 'Future<List>" error. same for the title.
What is the correct way to do this? To access this list in a futurebuilder or listbuilder.
Thanks alot in advance.
class _HomeScreenState extends State<HomeScreen> {
final storage = new FlutterSecureStorage();
Future<List<dynamic>> _loadedProducts;
@override
void initState() {
_loadedProducts = _getPolicy();
super.initState();
}
Future<void> _getPolicy() async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/todos/1');
try {
final response = await http.get(url);
final extractedData = json.decode(response.body);
final List<dynamic> loadedProducts = [];
extractedData.forEach((prodId, prodData) {
loadedProducts.addAll(extractedData);
});
_loadedProducts = loadedProducts;
print(_loadedProducts);
} catch (error) {
print('---error-');
throw (error);
}
}
Here is the code for the futurebuilder
FutureBuilder<List<dynamic>>(
future: _loadedProducts,
builder: (context, snapshot) {
if (snapshot.hasData) {
return AnimatedList(
initialItemCount: snapshot.data.length,
itemBuilder:
(BuildContext context, int index,
Animation animation) {
return new Text(_loadedProducts.title.toString());
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
);
CodePudding user response:
You need to return the list in your _getPolicy() future function. So try changing it like so:
Future<List<dynamic>> _getPolicy() async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/todos');
try {
final response = await http.get(url);
return json.decode(response.body);
} catch (error) {
print('---error-');
rethrow;
}
}
What I changed:
In your url, you are only getting one todo, so I removed /1 from your url. If instead you want to get all todos of the user with userId=1 then you can change the url to the following
https://jsonplaceholder.typicode.com/todos?userId=1
Also, the json.decode() already returns a list, so no need for your forEach
Moreover, you need to fix the text widget in your animated list as you can't use _loadedProducts.title. You need to use the snapshot data here. This is your FutureBuilder code after a few fixes:
FutureBuilder<List<dynamic>>(
future: _loadedProducts,
builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
if (snapshot.hasData && snapshot.data != null && snapshot.data!.isNotEmpty) {
return AnimatedList(
initialItemCount: snapshot.data!.length,
itemBuilder:
(BuildContext context, int index,
Animation animation) {
return new Text(snapshot.data![index]['title']);
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
);
