esentis / multiple_search_selection

A highly customizable multiple selection widget with fuzzy search functionality.
https://pub.dev/packages/multiple_search_selection
BSD 3-Clause "New" or "Revised" License
12 stars 13 forks source link

Failing to work with async data from API #14

Closed tinashepb closed 2 years ago

tinashepb commented 2 years ago

Good day.

Please could you kindly assist. I'm failing to work with data asynchronously fetched from an API for the dropdown. It seems I can only work predefined data.

Not sure if I'm making a mistake or there's a special way I need to access the data.

Regards.

esentis commented 2 years ago

Hello there ! What is the problem exactly ? Currently I have no .fromFuture constructor for the widget to autobuild after an async request. I will look into it and maybe I could add one.

What I would suggest is having a loading flag and keep on loading while your data is being fetched, after that you will have the data you need to populate the dropdown.

tinashepb commented 2 years ago

Thank you, I'll see if I can try that. I'd been using set state to update the list variable once the data fetch is complete though the data then isn't available in the dropdown though I can print it in console.

esentis commented 2 years ago

Hmm well that's weird, updating the list and using setState should have updated the dropdown. Would you mind sharing a minimal code to see what is going on ?

tinashepb commented 2 years ago

Sure, I've attached a file with the minimal code. It doesn't seem to be formatting correctly when I paste it here.

UPDATE: I have editted it for you

import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import '../constants.dart';
import '../helpers/network_client.dart';
import '../libraries/custom_multiselect.dart';
import '../libraries/locations_search.dart';
import '../models/country.dart';
import '../pages/search_results.dart';

class SearchForm extends StatefulWidget {
  final bool? filterText;
  const SearchForm({Key? key, this.filterText}) : super(key: key);

  @override
  State<SearchForm> createState() => _SearchFormState(filterText: filterText);
}

class _SearchFormState extends State<SearchForm> {
  bool isLoaded = false;
  //Search items
  List<Country> _locations = [];

  @override
  void initState() {
    super.initState();
    _searchCriteria();
  }

  void _searchCriteria() async {
    NetworkClient client =
        NetworkClient(path: '/search-criteria', method: 'get', parameters: {});
    var data = await client.runRequest();
    setState(() {
      data['locations']['provinces'].forEach((e) {
        _locations.add(Country(
            name: e['name'], id: 'Province_${e['id']}', type: 'Province'));
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(kPagePadding),
      color: kPrimaryColor,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: LocationsSearch<Country>(
              searchFieldTextStyle: TextStyle(
                height: kTextFieldStyleHeight,
              ),
              items: _locations, // List<Country>
              fieldToCheck: (c) {
                return c.name;
              },
              itemBuilder: (country) {
                return Padding(
                  padding: const EdgeInsets.all(0),
                  child: Container(
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(0),
                      color: Colors.white,
                    ),
                    child: Container(
                      decoration: BoxDecoration(
                          border: Border(
                        bottom: BorderSide(
                          color: Colors.grey.shade300,
                        ),
                      )),
                      child: Padding(
                        padding: const EdgeInsets.symmetric(
                          vertical: 10,
                          horizontal: 10,
                        ),
                        child: Row(
                          children: [
                            Expanded(
                              flex: 2,
                              child: Text(
                                country.name,
                              ),
                            ),
                            Expanded(
                              child: Text(
                                country.type,
                                textAlign: TextAlign.right,
                                style: TextStyle(
                                  color: Colors.grey.shade500,
                                  fontStyle: FontStyle.italic,
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                );
              },
              pickedItemBuilder: (country) {
                return Container(
                  decoration: const BoxDecoration(
                    color: kPrimaryColor,
                  ),
                  child: Padding(
                    padding:
                        const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
                    child: Wrap(children: [
                      RichText(
                        text: TextSpan(
                          children: [
                            TextSpan(
                              text: country.name + ' ',
                              style: TextStyle(
                                color: Colors.white,
                              ),
                            ),
                            WidgetSpan(
                              child: Icon(
                                Icons.cancel,
                                color: Colors.white,
                                size: 14.0,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ]),
                  ),
                );
              },
              onTapShowedItem: () {},
              onPickedChange: (items) {},
              onItemAdded: (item) {},
              onItemRemoved: (item) {},
              sortShowedItems: true,
              sortPickedItems: true,
              fuzzySearch: FuzzySearch.jaro,
              itemsVisibility: ShowedItemsVisibility.onType,
              showSelectAllButton: false,
              showClearAllButton: false,
              maximumShowItemsHeight: 200,
              showedItemsBackgroundColor: Colors.white,
              pickedItemsContainerMinHeight: 10,
            ),
          ),
          ],
      ),
    );
  }
}
esentis commented 2 years ago

Thanks for mentioning this ! There was currently a bug and the item list was not correctly rebuilding. The minimum Dart SDK has been also updated to 2.17.0 with the newest version of the library 2.3.0.

tinashepb commented 2 years ago

Thank you.