Home > Net >  Search array for listview filtering - Dart/Flutter
Search array for listview filtering - Dart/Flutter

Time:09-20

I am trying to integrate a search and filter textfield in my app, but I am not completely sure of the errors my compiler is throwing. I think I am having type issues, or that I have not set up my inheritances correctly? Ok, so basically I am sending a http request to an api and receiving this data where I have set up my class to display it. In a futurebuilder I have some conditional logic trying to sort the right data I need into separate lists(Im not sure if this the right thing to do but I digress) I then create a map (resultMap) and within that I loop through the arrays and nest a map (innerMap).

     class _HomePageState extends State<HomePage> {
      final controller = TextEditingController();
      String? searchString = '';
      late final Future<ProjectModel> futureProjects;

      List<ProjectSearch> searchList = []; //I think this causing this issues.....
      List<String?> jobNames = [];
      List<String?> jobNumbers = [];
      List<String?> techs = [];
      List<String?> pms = [];
      List<String?> address = [];
      List<String?> majors = [];
      List<String?> budget = [];
      Map resultMap = {};

      @override
       void initState() {
       super.initState();
       futureProjects = fetchProjects();
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
           title: const Text(
           'Upcoming / Live Projects',
           style: TextStyle(
            color: Colors.white,
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
        ),
        backgroundColor: ColorConstants.darkScaffoldBackgroundColor,
      ),
      drawer: const CustomDrawer(),
      backgroundColor: ColorConstants.lightScaffoldBackgroundColor,

      // ignore: avoid_unnecessary_containers
      body: Center(
        child: FutureBuilder<ProjectModel>(
            future: futureProjects,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                var data = snapshot.data!;
                var columns = data.columns;
                var rows = data.rows;

                for (var item in rows!) {
                  var cells = item.cells;
                  for (var elements in cells!) 
                    if (elements.columnId != null) {
                      if (elements.columnId == 2057691532158852) {
                        var displayValues = elements.displayValue;
                        if (displayValues != null) {
                          jobNames.add(displayValues);
                        }
                       ..... continuing conditional logic

     //Here is where I nest my arrays to the resultMap map:
                int index = 0;
                for (int i = 0; i < jobNames.length; i  ) {
                  Map innerMap = {};

                  innerMap['name'] = jobNames[index];
                  innerMap['address'] = address[index];
                  innerMap['jobNumber'] = jobNumbers[index];
                  innerMap['major'] = majors[index];
                  innerMap['tech'] = techs[index];
                  innerMap['pM'] = pms[index];
                  innerMap['budget'] = budget[index];

                  index  ;
                  resultMap[i] = innerMap;
                }

I have been looking trough some tutorials and it looks like it is easier to apply string search functions using .contains() but these only work on lists. So I convert my resultMap using a forEach to create my searchList list.

                resultMap.forEach((key, value) => searchList.add(value));

Here is my TextFormField:

                   TextFormField(
                          textAlign: TextAlign.center,
                          controller: controller,
                          onChanged: search,
                          .....

And then my ListView.builder:


                    return MaterialButton(
                      onPressed: () => showModalBottomSheet<void>(
                      backgroundColor: Colors.transparent,
                     context: context,
                      builder: (BuildContext context) {
                              final projectData = searchList[index];
                    return 
                          Text(
                             projectData['name'],

And finally the function I am using to search:

     void search(String query) {
       List finder = searchList;

        final suggestions = searchList.where((check) {
        final projectName = check['name'].toLowerCase();
        final input = query.toLowerCase();

         return projectName.contains(input);
         }).toList();

          setState(() {
           finder = suggestions;
          });
     }

I hope this makes sense... When I get rid of the model it doesn't break down but the search function doesnt filter thru the array. However here is the compile error:

    type 'List<dynamic>' is not a subtype of type 'List<ProjectModel>' of 'function 
     result'

CodePudding user response:

Try this showSearch() method

It is an inbuilt functionality which is simple to use.

CodePudding user response:

I think the problem arises when you convert map to list. please try below procedure to convert map to list when data comes from api...
obviously do anything(search) with list data in your app. just change api url from below

 Future<List<ProjectModel>> fetchProjectData() async {
        final response =
            await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
        if (response.statusCode == 200) {
          // If the server did return a 200 OK response,
          // then parse the JSON.
          final parsed = jsonDecode(response.body);
    
          return parsed.map<ProjectModel>((json) => ProjectModel.fromJson(json)).toList();
        } else {
          // If the server did not return a 200 OK response,
          // then throw an exception.
          throw Exception('Failed to load data');
        }
      }
  • Related