简体   繁体   中英

Variable scope withing the Flutter StatefulWidget

I'm trying to access the moviesList inside the build() and results as follows. Would appreciate if any could point out the real issue is. Thanks in advance.

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();
          },
        ));
  }
}

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 (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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM