skip to Main Content
import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:trilhaapp/model/post_model.dart';

class PostsRepository {
  Future<List<PostModel>> fetchPosts() async {
    var response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
    if (response.statusCode == 200) {
      var postList = jsonDecode(response.body);
      return (postList as List).map((e) => PostModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load post');
    }
  }
}

body: ListView.builder(
  itemCount: posts.length,
  itemBuilder: (_, index) {
    var post = posts[index];

When I attempt to populate this list, itemCount is 0, but I really shouldn’t be.

Am I fetching wrong?

2

Answers


  1. Please do refer this for the reference:

    In the below code we have handled the two things:

    1. Loader for the API call.
    2. Data addition and UI Decomposition after the api call.

    1. Loader for the API call:
    This has been handled by using the nullable state at the start named as postList.
    And in the build method please do observe that a ternary operator has been used to null check the state variable. Which checks the following:
    if the postList is null then CircleProgressIndicator will be shown. if the state is non-nullable then the UI will be started to get drawn.

    2. Data addition and UI Decomposition after the api call.

    Please do observe the following methods for understanding the API calls:

    • initState
    • postApiGetMethod

    The main function of data loading and the setState method is handled in the postApiGetMethod. Where the API is called and then the value from the api is decoded and it has been assigned to the state. And then the setState method is called ad the data is successfully loaded to the state.

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    
    class PostApiFetchScreen extends StatefulWidget {
      const PostApiFetchScreen({super.key});
    
      @override
      State<PostApiFetchScreen> createState() => _PostApiFetchScreenState();
    }
    
    class _PostApiFetchScreenState extends State<PostApiFetchScreen> {
    // NOTE - variable for holding the API Route
      final String _postApiFetchUrl = 'https://jsonplaceholder.typicode.com/posts';
    // NOTE - State for the data to draw the widget
      var postList = null;
    
    // NOTE - method for handling the API call and data assignment
      void postApiGetMethod() async {
        var response = await http.get(
          Uri.parse(_postApiFetchUrl),
        );
    // NOTE - Check for the successful data fetch
        if (response.statusCode == 200) {
          var responseBody = jsonDecode(response.body);
          print('Response data is ${responseBody.length}');
    // NOTE - Data Assignment
          postList = responseBody;
    // NOTE - setState for rebuilding the UI
          setState(() {});
        }
      }
    
      @override
      void initState() {
        super.initState();
        postApiGetMethod();
      }
    // NOTE - Widget of the overall post container
      Widget postContainer({
        required String title,
        required String body,
        required int id,
      }) {
        return Column(
          children: [
            const Divider(
              height: 2,
            ),
            postInfoTile(
              key: 'ID',
              pair: id.toString(),
            ),
            const SizedBox(
              height: 10,
            ),
            postInfoTile(
              key: 'Title',
              pair: title,
            ),
            const SizedBox(
              height: 10,
            ),
            postInfoTile(
              key: 'Body',
              pair: body,
            ),
            const SizedBox(
              height: 3,
            ),
            const Divider(
              height: 2,
            ),
          ],
        );
      }
    
    // NOTE - Widget for the post data holder
      Widget postInfoTile({
        required String key,
        required String pair,
      }) {
        return Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '$key:',
              style: const TextStyle(
                fontWeight: FontWeight.w900,
              ),
            ),
            const SizedBox(width: 20),
            Expanded(child: Text(pair)),
          ],
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text(
              'Post API Consume',
            ),
          ),
    // NOTE - handling the loader
          body: postList != null
              ? ListView.builder(
                  itemCount: postList.length,
                  itemBuilder: (context, index) => postContainer(
                    body: postList[index]['body'],
                    title: postList[index]['title'],
                    id: postList[index]['id'],
                  ),
                )
              : const Center(
                  child: CircularProgressIndicator(),
                ),
        );
      }
    }
    
    
    Login or Signup to reply.
  2. Use FutureBuilder and change your code like this:

    FutureBuilder<List<PostModel>>(
      future: PostsRepository().fetchPosts(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          List<PostModel> posts = snapshot.data;
          return ListView.builder(
            itemCount: posts.length,
            itemBuilder: (_, index) {
              var post = posts[index];
              // Build your list item using 'post'
            },
          );
        }
      },
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search