Home > Enterprise >  Flutter: How do I get futureBuilder to feed my custom widgets data?
Flutter: How do I get futureBuilder to feed my custom widgets data?

Time:07-07

I made a custom feedCard widget that accepts a heading, body, and image as parameters. My understanding of the FutureBuilder is a little lacking and after countless outdated tutorials I cant seem to get a feed running properly. I haven't setup firebase yet so I'm attempting to use a preset list of data for testing purposes which I believe is the area giving me issues.

This is my feed widget:

import 'package:flutter/material.dart';
import 'package:my_app/theme.dart';
import 'package:my_app/widgets/feed_card_widget.dart';

class Feed extends StatefulWidget {
  Feed({Key? key}) : super(key: key);

  @override
  State<Feed> createState() => _FeedState();
}

class _FeedState extends State<Feed> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: backgroundColor,
      body: SafeArea(
        child: Center(
          child: Column(
            children: [
              Expanded(
                child: FutureBuilder(
                  future: _getPosts(),
                  builder: (context, AsyncSnapshot snapshot) {
                    if (snapshot.data == null) {
                      return const Center(
                        child: Text('Loading'),
                      );
                    } else {
                      return ListView.builder(
                        itemCount: snapshot.data.length,
                        itemBuilder: (context, index) {
                          return FeedCard(
                            headingText: snapshot.data[index].headingText,
                            bodyText: snapshot.data[index].bodyText,
                          );
                        },
                      );
                    }
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class Post {
  final int index;
  final String headingText;
  final String bodyText;

  Post(
    this.index,
    this.headingText,
    this.bodyText,
  );
}

List<Post> postList = <Post>[
  Post(1, 'headingText', 'bodyText'),
  Post(2, 'headingText', 'bodyText'),
  Post(3, 'headingText', 'bodyText'),
  Post(4, 'headingText', 'bodyText'),
  Post(5, 'headingText', 'bodyText'),
];

//Future function
Future<List<Post>> _getPosts() async {
  var postData = postList;

  //List being returned
  List<Post> posts = [];

  for (var p in postData) {
    Post post = Post(
      p['index'],
      p['headingText'],
      p['bodyText'],
    );
    posts.add(post);
  }

  print(posts.length);

  return posts;
}

And the trouble line of code is:

    Post post = Post(
      p['index'],
      p['headingText'],
      p['bodyText'],
    );
    posts.add(post);
  }

CodePudding user response:

First of all, your postData is already has a type of List. But you're trying to convert it into List which is not necessary.

  • If you want your mock data to be already in List class. Just test it like this:
import 'dart:async';

Future<List<Post>> _getPosts() async {
    return Future.delayed(Duration(milliseconds: 500))
        .then((onValue) => postList);
}
  • Else, if you want your mockdata to be json and convert it into List<Post>, save your mock .json file in assets/mock folder

  • then, add factory constructor to Post class

class Post {
  final int index;
  final String headingText;
  final String bodyText;

  Post({
    this.index,
    this.headingText,
    this.bodyText,
  });

  factory Post.fromJson(Map<String, dynamic> data) {
    final index = data['index'] as int;
    final headingText = data['headingText'] as String;
    final bodyText = data['bodyText'] as String;
    return Post(index: index, headingText: headingText, bodyText: bodyText);
  }
}

then load your json file->convert it -> return it

import 'dart:convert';
import 'package:flutter/services.dart';

Future<List<Post>> _getPosts() async {
    String response = await rootBundle.loadString('mock/your_file_name.json');
    Map<String, dynamic> parsedJson = json.decode(response);

    await Future.delayed(const Duration(seconds: 1));

    final postList = Post.fromJson(parsedJson);

    return postList;
  }
  • Related