I trying to build a suggestion when I search some name of a country, so I use Type Ahead but it not working. Ncov19 class have properties is String Country When I implement it on TypeAheadField it is return null but I use TextField to work with getCountrySuggestion
import 'package:covid19_app/bloc/ncov19_bloc.dart';
import 'package:covid19_app/bloc/ncov19_event.dart';
import 'package:covid19_app/bloc/ncov19_state.dart';
import 'package:covid19_app/models/ncov_19.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
class Ncov19Screen extends StatefulWidget {
@override
_Ncov19ScreenState createState() => _Ncov19ScreenState();
}
class _Ncov19ScreenState extends State<Ncov19Screen> {
@override
void initState() {
BlocProvider.of<Ncov19Bloc>(context).add(Ncov19RequestAll());
super.initState();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context);
return SafeArea(
child: Scaffold(
body: Column(
children: [
Container(
padding: EdgeInsets.all(16),
child: TypeAheadField<Ncov19>(
suggestionsCallback: (value) async {
return await BlocProvider.of<Ncov19Bloc>(context)
.ncov19repository
.ncov19apiClient
.getCountrySuggestions(value);
},
)),
Container(
width: size.size.width * 0.95,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(10)),
margin: EdgeInsets.all(10),
child: TextFormField(
decoration: InputDecoration(
hintText: 'Đất nước', icon: Icon(Icons.search)),
onFieldSubmitted: (value) {
BlocProvider.of<Ncov19Bloc>(context)
.add(Ncov19RequestByCountry(country: value));
},
),
),
Expanded(
child: BlocBuilder<Ncov19Bloc, Ncov19State>(
builder: (context, state) {
if (state is Ncov19Initial) {
return Center(child: Text('Chọn đất nước'));
}
if (state is Ncov19LoadInProgress) {
return Center(
child: CircularProgressIndicator(),
);
}
if (state is Ncov19LoadSuccessCountry) {
final ncov19 = state.ncov19;
return ListView.builder(
itemCount: ncov19.length,
itemBuilder: (context, int) =>
Text('${ncov19[int].country}'),
);
}
if (state is Ncov19LoadSuccessAllCountry) {
final ncov19All = state.ncov19All;
return ListView(
children: [
Center(
child: Text('${ncov19All.confirmed}'),
)
],
);
}
if (state is Ncov19LoadFailure) {
return Text(
state.error,
style: TextStyle(color: Colors.red),
);
}
},
),
)
],
),
),
);
}
}
Here is a Bloc: State:
`
import 'package:covid19_app/models/ncov19_all.dart';
import 'package:covid19_app/models/ncov_19.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
abstract class Ncov19State extends Equatable {
const Ncov19State();
@override
List<Object> get props => [];
}
class Ncov19Initial extends Ncov19State {}
class Ncov19LoadInProgress extends Ncov19State {}
class Ncov19LoadSuccessCountry extends Ncov19State {
final List<Ncov19> ncov19;
Ncov19LoadSuccessCountry({@required this.ncov19});
@override
List<Object> get props => [];
}
class Ncov19LoadSuccessAllCountry extends Ncov19State {
final Ncov19All ncov19All;
Ncov19LoadSuccessAllCountry({@required this.ncov19All});
@override
List<Object> get props => [];
}
class Ncov19LoadFailure extends Ncov19State {
final String error;
Ncov19LoadFailure(this.error);
}
`
Event:
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
abstract class Ncov19Event extends Equatable {
const Ncov19Event();
}
class Ncov19RequestByCountry extends Ncov19Event {
final String country;
const Ncov19RequestByCountry({@required this.country});
@override
List<Object> get props => [];
}
class Ncov19RequestAll extends Ncov19Event {
const Ncov19RequestAll();
@override
List<Object> get props => [];
}
Bloc:
`import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:covid19_app/models/ncov19_all.dart';
import 'package:covid19_app/models/ncov_19.dart';
import 'package:covid19_app/repositories/ncov19_repository.dart';
import 'package:flutter/foundation.dart';
import 'ncov19_event.dart';
import 'ncov19_state.dart';
class Ncov19Bloc extends Bloc<Ncov19Event, Ncov19State> {
final Ncov19Repository ncov19repository;
Ncov19Bloc({@required this.ncov19repository}) : super(Ncov19Initial());
@override
Stream<Ncov19State> mapEventToState(
Ncov19Event event,
) async* {
if (event is Ncov19RequestByCountry) {
yield Ncov19LoadInProgress();
try {
final List<Ncov19> ncov19 =
await ncov19repository.getCountrySuggestions(event.country);
yield Ncov19LoadSuccessCountry(ncov19: ncov19);
} catch (error) {
yield Ncov19LoadFailure(error.toString());
}
}
if (event is Ncov19RequestAll) {
yield Ncov19LoadInProgress();
try {
final Ncov19All ncov19All = await ncov19repository.getNcov19ByAll();
yield Ncov19LoadSuccessAllCountry(ncov19All: ncov19All);
} catch (error) {
yield Ncov19LoadFailure(error.toString());
}
}
}
}
`
Ncov19_api_client:
import 'dart:convert';
import 'package:covid19_app/models/ncov19_all.dart';
import 'package:covid19_app/models/ncov_19.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import '../models/ncov_19.dart';
class Ncov19ApiClient {
static const baseUrl = 'https://covid-api.mmediagroup.fr/v1/cases';
final http.Client httpClient;
Ncov19ApiClient({@required this.httpClient});
// Future<Ncov19> fetNcov19ByCountry(String country) async {
// final ncov19Url = '$baseUrl?country=$country';
// final ncov19Response = await this.httpClient.get(Uri.parse(ncov19Url));
// if (ncov19Response.statusCode != 200) {
// throw Exception('Lỗi truy cập');
// }
// final ncov19Json = jsonDecode(ncov19Response.body);
// return Ncov19.fromJson(ncov19Json);
// }
Future<List<Ncov19>> getCountrySuggestions(String query) async {
final url = Uri.parse('https://covid-api.mmediagroup.fr/v1/cases');
final responseCountry = await this.httpClient.get(url);
if (responseCountry.statusCode != 200) {
throw Exception('Lỗi truy cập');
}
final Map<String, dynamic> nCov19AllCountry =
json.decode(responseCountry.body);
return nCov19AllCountry.entries
.map((json) => Ncov19(country: json.key))
.where((nCov) {
final queryUpperFisrt =
'${query[0].toUpperCase()}${query.substring(1).toLowerCase()}';
final countryUpperFisrt =
'${nCov.country[0].toUpperCase()}${nCov.country.substring(1).toLowerCase()}';
return countryUpperFisrt.contains(queryUpperFisrt);
}).toList();
}
Future<Ncov19All> fetNcov19All() async {
final ncov19Url = '$baseUrl';
final ncov19Response = await this.httpClient.get(Uri.parse(ncov19Url));
if (ncov19Response.statusCode != 200) {
throw Exception('Lỗi truy cập');
}
final ncov19AllJson = jsonDecode(ncov19Response.body);
return Ncov19All.fromJson(ncov19AllJson);
}
}
repositories:
import 'package:covid19_app/models/ncov19_all.dart';
import 'package:covid19_app/models/ncov_19.dart';
import 'package:covid19_app/repositories/ncov19_api_client.dart';
import 'package:flutter/foundation.dart';
class Ncov19Repository {
final Ncov19ApiClient ncov19apiClient;
Ncov19Repository({@required this.ncov19apiClient});
// Future<Ncov19> getNcov19ByCountry(String country) async {
// return ncov19apiClient.fetNcov19ByCountry(country);
// }
Future<List<Ncov19>> getCountrySuggestions(String query) async {
return ncov19apiClient.getCountrySuggestions(query);
}
Future<Ncov19All> getNcov19ByAll() async {
return ncov19apiClient.fetNcov19All();
}
}
Main:
import 'package:covid19_app/bloc/ncov19_bloc.dart';
import 'package:covid19_app/repositories/ncov19_api_client.dart';
import 'package:covid19_app/repositories/ncov19_repository.dart';
import 'package:covid19_app/screens/ncov19_screen.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
final Ncov19Repository ncov19repository = Ncov19Repository(
ncov19apiClient: Ncov19ApiClient(
httpClient: http.Client(),
));
runApp(MyApp(ncov19repository: ncov19repository));
}
class MyApp extends StatelessWidget {
final Ncov19Repository ncov19repository;
const MyApp({Key key, @required this.ncov19repository}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider<Ncov19Bloc>(
create: (context) => Ncov19Bloc(ncov19repository: ncov19repository),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Ncov19 tracker',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Ncov19Screen(),
),
);
}
}
Am I missing something or doing wrong?