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/";
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