'Variable scope within the Flutter StatefulWidget
I'm trying to access the moviesList
inside the build()
and results as follows. What is the real issue?
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building MyListScreen(dirty, state:
flutter: _MyListScreenState#21007):
flutter: The getter 'results' was called on null.
flutter: Receiver: null
flutter: Tried calling: results
The code snippet followed as below:
class _MyListScreenState extends State<MyListScreen> {
MoviesList moviesList;
_getLatestMovies() {
APIService.getMoviesNowPlaying().then((response) {
setState(() {
final jsonData = json.decode(response.body);
moviesList = new MoviesList.fromJson(jsonData);
// moviesList(new MoviesList.fromJson(jsonData));
for (var i = 0; i < moviesList.results.length; i++) {
print(moviesList.results[i].title);
}
});
});
}
@override
initState() {
super.initState();
_getLatestMovies();
}
@override
Widget build(context) {
return Scaffold(
appBar: AppBar(
title: Text("View Title"),
),
body: ListView.separated(
padding: EdgeInsets.zero,
itemCount: moviesList.results.length,
itemBuilder: (context, index) {
// return ListTile(title: Text(moviesList.results[index].title));
},
separatorBuilder: (context, index) {
return Divider();
},
));
}
}
Solution 1:[1]
Use
itemCount: moviesList != null ? moviesList.results.length : 0,
Your build()
was getting called before moviesList
was initialised, so here we first check for null
, if null
use 0
as itemCount
else use its length.
Solution 2:[2]
Solution (probably one):
The real reason behind the issue wasn't variable scope, rather it was the way async did was completely wrong, a redesign solved the issue. Moved _getLatestMovies();
inside the FutureBuilder.
Improved one pasted below:
@override
Widget build(context) {
var futureBuilder = FutureBuilder(
future: _getLatestMovies(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return ListView.separated(
padding: EdgeInsets.zero,
with this move, the FutureBuilder
awaits the result from the method and passed onto the ListView as a snapshot.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |