flutterdartdart-html

Is there a way to make a search function make an api call to return a list and go to a results page in dart?


I'm trying to make a book app and am trying to make a search bar that will append what I typed into a URL and perform a get. I am struggling to get the search text to the API and change the page.

This is my Main.dart:

import 'package:betterreadsui/api_calls.dart';
import 'package:flutter/material.dart';
import 'signUp.dart';
import 'searchResults.dart';
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Better Reads',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: "Better Reads"),
      
      
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});



  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final SearchController controller;
  @override
  void initState() {
    super.initState();
    controller = SearchController();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      bottomNavigationBar: BottomNavigationBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        items:const <BottomNavigationBarItem> [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home'
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.library_books_rounded),
            label: 'My Books'
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: 'Settings'
          ),
        ],
      ),
      
      body:  HomePage( ctrl: controller,)//this line calls my home page and a
    );
  }
  
}
//lays out the homepage
class HomePage extends StatelessWidget {
  const HomePage({super.key, required this.ctrl});
  final SearchController ctrl;
  @override
  Widget build(BuildContext context){
    
    return   Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Align(
          alignment: Alignment.topRight,
          child: Padding(
            padding:const EdgeInsets.only(top: 10),
            child: SearchBar(
              controller: ctrl,
              leading:const  IconButton(
                icon: Icon(Icons.search_rounded),
                onPressed:  (search){
                  searchurl = searchurl + search;
                  Navigator.of(context).push(MaterialPageRoute(builder: (context)=>const SearchResults()));
                },
              ),
              trailing:const  <Widget>[ 
                IconButton(
                  onPressed: null, 
                  icon: Icon(Icons.camera_alt_rounded)
                ),
              ],
            ),
          ),
        ),
        //Place holder lists not full implemented yet and probably not related to my problem
        const Text(
          'Your Books',
        ),
        const SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: Row(
            children: <Widget>[
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.black,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.blue,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.red,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.green,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.pink,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.purple,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.orange,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.brown,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
              SizedBox(
                height: 100,
                width: 50,
                child: Placeholder(
                  color: Colors.grey,
                  fallbackHeight: 100,
                  fallbackWidth: 50,
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }
  //tried to use this function but still gave me errors in on pressed
  void searchBtn(String search, BuildContext context){
    searchurl = searchurl + search;
    Navigator.push(context, MaterialPageRoute(builder: (context)=>const SearchResults()));
  }
}



This is the controller:

late final SearchController controller;
  @override
  void initState() {
    super.initState();
    controller = SearchController();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

This is where I plan to put API calls This is my API-call.dart:

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

import 'dart:convert';

Future<List<Book>> fetchBooks() async {
  final response = await http.get(Uri.parse(searchurl));
  if(response.statusCode==200){
    var json = response.body;
    //log('data: $json');
    return decodeBook(json);
  }else{
    throw Exception("Somtehing went wrong");
  }
}
List<Book> decodeBook(String responseBody){
  final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
  return  parsed.map<Book> ((json)=>Book.fromMap(json)).toList();
}

String searchurl = "http://10.0.2.2:8080/Books/";

Solution

  • I think part of my issue was trying to use a search bar that wasn't attached to an app bar but my biggest issue was I had no controller linked to what I changed to a text feild