Michał Śniady
Michał Śniady

Reputation: 159

How to filter Future List in Flutter?

I need help with filtering the list.

I populate the list in initState:

  Future _organisations;

  Future<void> readJson() async {
    final String response =
        await rootBundle.loadString('assets/organisations.json');
    final data = await json.decode(response);

    List<Organization> temp = [];

    for (var item in data) {
      Organization place = Organization(
        address: item['Address'],
        contactInfo: item['Contact info'],
        organization: item['Organization'],
        phoneNumber: item['Phone number'],
        shortDescription: item['Short description'],
        subject: item['Subject'],
        tags: item['Tags'],
      );

      temp.add(place);
    }

    temp.sort((a, b) => a.organization.compareTo(b.organization));

    return temp;
  }

  @override
  void initState() {
    super.initState();
    _organisations = readJson();
  }

Then I have a button above the list that I want to use to filter the list with setState, however it doesn't work. How can I filter List of type Future?

Upvotes: 0

Views: 2485

Answers (2)

William Cardenas
William Cardenas

Reputation: 86

Future<void> doesn’t return anything. If you want it to return a list it should be Future<List>. When you sort the items in the list, what are you comparing them against? Of what type is item[“organisation”]? It needs to be of a comparable type.

Upvotes: 0

Guillaume Roux
Guillaume Roux

Reputation: 7308

First of all your method readJson() has a return value of type Future<void> which means you will never be able to get your List<Organization> returned.

Moreover you are working with asynchronous operations which means that you will need to use either await or then to get your value at some points.

Here is an example of how you could fix your code:

List<Organization> _organisations;

// Simply change the return type to Future<List<Organization>>
Future<List<Organization>> readJson() async {
  final String response =
    await rootBundle.loadString('assets/organisations.json');
  final data = await json.decode(response);

  List<Organization> temp = [];

  for (var item in data) {
    Organization place = Organization(
      address: item['Address'],
      contactInfo: item['Contact info'],
      organization: item['Organization'],
      phoneNumber: item['Phone number'],
      shortDescription: item['Short description'],
      subject: item['Subject'],
      tags: item['Tags'],
    );
    temp.add(place);
  }

  /// Then you need to compare objects that are comparable.
  /// For example if you want to sort your items by their address :
  temp.sort((a, b) =>
    a.address.toLowerCase().compareTo(b.address.toLowerCase())
  );

  return temp;
}

@override
void initState() {
  super.initState();
  
  /// As you cannot use await in initState you can use then
  /// to perform an action once your asynchronous operation is
  /// done.
  ///
  /// In this case I am assigning the value to _organisations
  /// and causing a rebuild of the interface with setState.
  readJson().then((List<Organization> temp) {
    setState(() => _organisations = temp);
  });
}

Upvotes: 1

Related Questions