-3

I have an app where homePage display list of post using json after clicking post i need to navigate/show the post comment list according using provider . how to do that?

A screen to list all the posts. https://jsonplaceholder.typicode.com/posts A post detail screen which have list of comments. https://jsonplaceholder.typicode.com/posts/{post_id}/comments

HomePage:

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    // TODO: implement initState
    final provider = Provider.of<GetPostProvider>(context, listen: false);
    provider.getMyData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final provider = Provider.of<GetPostProvider>(context);

    return Scaffold(
        appBar: AppBar(
          title: const Text('User Id'),
        ),
        body: ListView.builder(
            itemCount: provider.postModelClass.length,
            itemBuilder: ((context, index) {
              return Card(child: Consumer<GetPostProvider>(
                builder: (context, value, child) {
                  return ListTile(
                    onTap: () {
                      Navigator.push(context, MaterialPageRoute(builder: (_) {
                        return CommentScreen(
                            postModelClass: value.postModelClass[index]);
                        //here comes error
                      }));
                    },
                    leading: CircleAvatar(
                      child: Text("${value.postModelClass[index].id}"),
                    ),
                    title: Text("${value.postModelClass[index].title}"),
                  );
                },
              ));
            })));
  }
}

CommentPage:

class CommentPage extends StatefulWidget {
  final CommentModel postModelClass;
  const CommentPage({
    Key? key,
    required this.postModelClass,
  }) : super(key: key);

  @override
  State<CommentPage> createState() => _CommentPageState();
}

class _CommentPageState extends State<CommentPage> {
  @override
  Widget build(BuildContext context) {
    final commentprovider = Provider.of<GetCommentProvider>(context);
    return Scaffold(
        appBar: AppBar(),
        body: ListView.builder(
            itemCount: commentprovider.comment.length,
            itemBuilder: ((context, index) {
              return Text(commentprovider.comment[index].email.toString());
            })));
  }
}

PostDetailModel:

class PostModelClass {
  int? userId;
  int? id;
  String? title;
  String? body;
  PostModelClass({
    this.userId,
    this.id,
    this.title,
    this.body,
  });

  Map<String, dynamic> toJson() {
    return {'userId': userId, 'id': id, 'title': title, 'body': body};
  }

  factory PostModelClass.fromJson(Map<String, dynamic> data) {
    final userId = data['userId'];
    final id = data['id'];
    final title = data['title'];
    final body = data['body'];
    return PostModelClass(id: id, userId: userId, title: title, body: body);
  }
}

CommentModel:

class CommentModel {
  int? userId;
  int? id;
  String? name;
  String? email;
  String? body;
  CommentModel({
    this.userId,
    this.id,
    this.name,
    this.email,
    this.body,
  });

  Map<String, dynamic> toJson() {
    return {
      'userId': userId,
      'id': id,
      'name': name,
      'email': email,
      'body': body
    };
  }

  factory CommentModel.fromJson(Map<String, dynamic> data) {
    final userId = data['userId'];
    final id = data['id'];
    final name = data['name'];
    final email = data['email'];
    final body = data['body'];
    return CommentModel(
        userId: userId, id: id, name: name, email: email, body: body);
  }
}

PostProvider:

class GetPostProvider with ChangeNotifier {
  bool isLoading = false;

  List<PostModelClass> postModelClass = [];

  getMyData() async {
    isLoading = true;
    postModelClass = await getAllPost();
    isLoading = false;
    notifyListeners();
  }

  Future<List<PostModelClass>> getAllPost() async {
    final response =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    List<PostModelClass> mylist = [];

    try {
      if (response.statusCode == 200) {
        final jsonDecode = await json.decode(response.body);
        for (var i in jsonDecode) {
          PostModelClass _model = PostModelClass.fromJson(i);
          mylist.add(_model);
        }
        return mylist;
      } else {
        return mylist;
      }
    } catch (e) {
      throw 'aaaaaaaaaa';
    }
  }
}

CommentProvider:

class GetCommentProvider with ChangeNotifier {
  bool isLoading = false;

  List<CommentModel> comment = [];

  late int userId;

  getComment() async {
    isLoading = true;
    comment = await getAllComment(userId);
    isLoading = false;
    notifyListeners();
  }

  Future<List<CommentModel>> fetchComment(int id) async {
    final response = await http.get(
        Uri.parse('https://jsonplaceholder.typicode.com/posts/${id}/comments'));

    try {
      if (response.statusCode == 200) {
        final jsonDecode = json.decode(response.body)['comments'] as List;
        return jsonDecode
            .map((comments) => CommentModel.fromJson(comments))
            .toList();
      } else {
        throw Exception('Failed to load model');
      }
    } catch (e) {
      throw 'error + $e';
    }
  }

  Future<List<CommentModel>> getAllComment(int userId) async {
    final response = await http.get(Uri.parse(
        'https://jsonplaceholder.typicode.com/posts/$userId/comments'));
    List<CommentModel> mylist = [];

    try {
      if (response.statusCode == 200) {
        final jsonDecode = await json.decode(response.body);
        for (var i in jsonDecode) {
          CommentModel _model = CommentModel.fromJson(i);
          mylist.add(_model);
        }
        return mylist;
      } else {
        return mylist;
      }
    } catch (e) {
      throw 'aaaaaaaaaa';
    }
  }
}
julemand101
  • 28,470
  • 5
  • 52
  • 48
Dhiraj
  • 17
  • 4
  • is the problem when reading data from JSON file? because here u wrote [ final jsonDecode=json.decode(response.body)['comments'] as List; ] and there is no 'comments' attribute in JSON body. – Amina Bekir Aug 21 '22 at 10:27
  • The method 'CommentScreen' isn't defined for the type '_HomePageState'. – Dhiraj Aug 21 '22 at 10:52
  • you called 'CommentScreen' and the class name is 'CommentPage' – Amina Bekir Aug 21 '22 at 10:57
  • i am still unbalie to display comment through id. please help me https://github.com/Dhiraj1424/id – Dhiraj Aug 21 '22 at 11:09
  • i checked out your code and saw that you called ' comment = await getAllComment(userId);' inside ' getComment()' function, but you didn't call this one. – Amina Bekir Aug 21 '22 at 12:36

3 Answers3

0

I think the value itself is a list of postModelClass so you can use the following command to access it

postModelClass.value[index];
Kaushik Chandru
  • 15,510
  • 2
  • 12
  • 30
0

To get comments for a specific post:

Update your GetCommentProvider class

class GetCommentProvider with ChangeNotifier {

  List<CommentModel> comment = [];

  ....

  getComment(int postId) async {
    isLoading = true;
    comment = await fetchComment(postId);//update
    isLoading = false;
    notifyListeners();
  }
 ....
 ....
}

Then in the initState() of the CommentPage add this

@override
void initState() {
  final provider = Provider.of<GetCommentProvider>(context, listen: false);
  provider.getComment(widget.postModelClass.id);//update
}
-1

The easiest way to read a value is by using the extension methods on [BuildContext]:

  • context.watch(), which makes the widget listen to changes on T
  • context.read(), which returns T without listening to it.

Update your CommentPage:

class _CommentPageState extends State<CommentPage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    context.read<GetCommentProvider>().getComment(widget.postModelClass.id!);
  }

  @override
  Widget build(BuildContext context) {
    final commentProvider = context.watch<GetCommentProvider>();
    return Scaffold(
      appBar: AppBar(),
      body: ListView.builder(
        itemCount: commentProvider.comment.length,
        itemBuilder: ((context, index) {
          return Text(commentProvider.comment[index].email.toString());
        }),
      ),
    );
  }
}

And fixes GetCommentProvider:

class GetCommentProvider with ChangeNotifier {
    
    ...
    
    getComment(int postId) async {
    isLoading = true;
    comment = await getAllComment(postId);
    isLoading = false;
    notifyListeners();
    }

   ...