5

I am fairly new to using REST API to GET data and display in a Listview in Flutter. I have since been working on something like this, But i get Lost along the line. Hence I need Help with this.

My code Goes thus

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';

import 'package:http/http.dart' as http;

class TransactionDetails {
  final String avatar;
  final String name;
  final String date;
  final String amount;

  TransactionDetails({required this.avatar, required this.name, required this.date, required this.amount});

  factory TransactionDetails.fromJson(Map<String, dynamic> json) {
    return TransactionDetails(
        avatar: json['avatar'],
        name: json['name'],
        date: json['date'],
        amount: json['amount']);
  }
}

class BaseScreen extends StatelessWidget {
  const BaseScreen({Key? key}) : super(key: key);

  Future<TransactionDetails> fetchTransaction() async {
    final response = await http
        .get('https://brotherlike-navies.000webhostapp.com/people/people.php');

    if (response.statusCode == 200) {
      return TransactionDetails.fromJson(json.decode(response.body));
    } else {
      throw Exception('Request Failed.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          width: double.infinity,
          height: 150,
          child: ListView(
            scrollDirection: Axis.horizontal,
            children: [
              Container(
                margin: const EdgeInsets.all(15),
                width: 319,
                height: 100,
                color: Colors.green,
                alignment: Alignment.center,
                child: const Text(
                  '\$5200.00',
                  style: TextStyle(
                      fontSize: 15,
                      color: Colors.white,
                      fontWeight: FontWeight.bold),
                ),
              ),
              Container(
                margin: const EdgeInsets.all(15),
                width: 319,
                height: 100,
                color: Colors.green,
                alignment: Alignment.center,
                child: const Text(
                  '\$1200.00',
                  style: TextStyle(
                      fontSize: 15,
                      color: Colors.white,
                      fontWeight: FontWeight.bold),
                ),
              ),
              SizedBox(height: 24),
            ],
          ),
        ),
        Padding(
          padding: EdgeInsets.all(15),
          child: Text(
            "Recent Transactions",
            style: TextStyle(
                fontSize: 14, fontWeight: FontWeight.bold, color: Colors.green),
          ),
        ),
        ListView() //Display the data here from the REST API
      ],
    )));
  }
}

How do I Display it on the Listview? Please I need help with this. Just for the sake of clarification as I am learning here with this.

1
  • @M.Eriksson removed, Please how do i display data from the endpoint in a Listview Commented Sep 27, 2022 at 8:19

2 Answers 2

8

Try below code:

Your TransactionDetails Class

class TransactionDetails {
  String? avatar;
  String? name;
  String? date;
  String? amount;

  TransactionDetails({
    this.avatar,
    this.name,
    this.date,
    this.amount,
  });

  TransactionDetails.fromJson(Map<String, dynamic> json) {
    avatar = json['avatar'];
    name = json['name'];
    date = json['date'];
    amount = json['amount'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['avatar'] = avatar;
    data['name'] = name;
    data['date'] = date;
    data['amount'] = amount;
    return data;
  }
}

API Call:

 Future<List<TransactionDetails>> fetchAlbum() async {
    final response = await http.get(Uri.parse(
        'https://brotherlike-navies.000webhostapp.com/people/people.php'));

    if (response.statusCode == 200) {
      final List result = json.decode(response.body);
      return result.map((e) => TransactionDetails.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load data');
    }
  }

Your Widget:

Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          width: double.infinity,
          height: 150,
          child: ListView(
            scrollDirection: Axis.horizontal,
            children: [
              Container(
                margin: const EdgeInsets.all(15),
                width: 319,
                height: 100,
                color: Colors.green,
                alignment: Alignment.center,
                child: const Text(
                  '\$5200.00',
                  style: TextStyle(
                      fontSize: 15,
                      color: Colors.white,
                      fontWeight: FontWeight.bold),
                ),
              ),
              Container(
                margin: const EdgeInsets.all(15),
                width: 319,
                height: 100,
                color: Colors.green,
                alignment: Alignment.center,
                child: const Text(
                  '\$1200.00',
                  style: TextStyle(
                      fontSize: 15,
                      color: Colors.white,
                      fontWeight: FontWeight.bold),
                ),
              ),
              const SizedBox(height: 24),
            ],
          ),
        ),
        const Padding(
          padding: EdgeInsets.all(15),
          child: Text(
            "Recent Transactions",
            style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.bold,
                color: Colors.green),
          ),
        ),
        Center(
          child: FutureBuilder<List<TransactionDetails>>(
            future: fetchAlbum(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  shrinkWrap: true,
                  itemCount: snapshot.data!.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      leading: CircleAvatar(
                        child: Image.network(
                            snapshot.data![index].avatar.toString()),
                      ),
                      title: Text(snapshot.data![index].name.toString()),
                      trailing:
                          Text(snapshot.data![index].amount.toString()),
                      subtitle: Text(snapshot.data![index].date.toString()),
                    );
                  },
                );
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              } 
              return const CircularProgressIndicator();
            },
          ),
        ),
      ],
    ),

Result Screen-> image

Sign up to request clarification or add additional context in comments.

3 Comments

great solution, its work for me, but after 10 seconds, failed with status code 429 (too many requests), could you please help me how to handle this? thanks alot
@ElvisSonathaDanListi this is server side error, BTW how can I help you?
thanks, i'll try to fix my server side
2

There are multiple ways you can achieve this.

  1. Using FutureBuilder
  2. Using StatefulWidget & setState

Currently, you are using a StatelessWidget (BaseScreen) so let's just go with FutureBuilder.

On hitting the url that you have given: https://brotherlike-navies.000webhostapp.com/people/people.php

It gives the following response:

[{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/002\/002\/403\/small\/man-with-beard-avatar-character-isolated-icon-free-vector.jpg","name":"Kayo Johnson","date":"09\/29\/2022","amount":"5000.00"},{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/002\/002\/403\/small\/man-with-beard-avatar-character-isolated-icon-free-vector.jpg","name":"Kuta Joy","date":"09\/29\/2022","amount":"5000.00"},{"avatar":"https:\/\/static.vecteezy.com\/system\/resources\/thumbnails\/001\/993\/889\/small\/beautiful-latin-woman-avatar-character-icon-free-vector.jpg","name":"Timmi Phillips","date":"09\/28\/2022","amount":"3500.00"}]

It returns a list of transaction details objects. Hence, you should add another method in your model TransactionDetail which will return a list of TransactionDetails as follows:

class TransactionDetails {
  final String avatar;
  final String name;
  final String date;
  final String amount;

  TransactionDetails(
      {required this.avatar,
      required this.name,
      required this.date,
      required this.amount});

  factory TransactionDetails.fromJson(Map<String, dynamic> json) {
    return TransactionDetails(
        avatar: json['avatar'],
        name: json['name'],
        date: json['date'],
        amount: json['amount']);
  }

  static List<TransactionDetails> fromJsonList(dynamic jsonList) {
    final transactionDetailsList = <TransactionDetails>[];
    if (jsonList == null) return transactionDetailsList;

    if (jsonList is List<dynamic>) {
      for (final json in jsonList) {
        transactionDetailsList.add(
          TransactionDetails.fromJson(json),
        );
      }
    }

    return transactionDetailsList;
  }
}

Update your fetchTransaction method as follows:

Future<List<TransactionDetails>> fetchTransaction() async {
    final response = await http
        .get('https://brotherlike-navies.000webhostapp.com/people/people.php');

    if (response.statusCode == 200) {
      return TransactionDetails.fromJsonList(json.decode(response.body));
    } else {
      throw Exception('Request Failed.');
    }
  }

Just wrap your ListView widget with a FutureBuilder widget as follows:

    FutureBuilder(
      future: fetchTransaction(),
      builder: (context, AsyncSnapshot<List<TransactionDetails>> snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.data == null) {
            return const Center(child: Text('Something went wrong'));
          }

          return ListView.builder(
              itemCount: snapshot.data?.length ?? 0,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(snapshot.data![index].name),
                  subtitle: Text(snapshot.data![index].amount),
                );
              });
        }
        return const CircularProgressIndicator();
      },
    ),

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.