error in implementing search feature in Listview builder - flutter

I'm trying to implement search functionality in the list view builder But I don't have an idea to implement it.
this is model class
class Contacts {
String? id;
String? name;
String? display_name;
Contacts({this.id, this.name, this.display_name});
factory Contacts.fromJson(Map<String?, dynamic> json) {
return Contacts(
id: json['id'], name: json['name'], display_name: json['display_name']);
}
Map toJson() => {'id': id, 'name': name, "display_name": display_name};
}
this is the future class
late Future<List<Contacts>> c;
void onInit() async {
c = getContacts();
}
Future<List<Contacts>> getContacts() async {
print("<<<<<GETTING CONTACTS>>>>>>");
// SERVER API URL
Uri url = Uri.parse('http://localhost:8000/get-contacts');
// Store all data with Param Name.
var data = {'sender': id};
//json encode
String? body = json.encode(data);
// Starting Web API Call.
var response = await http.post(url,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: body);
// If Web call Success than Hide the CircularProgressIndicator.
if (response.statusCode == 200) {
final datas = json.decode(response.body).cast<Map<String, dynamic>>();
contacts = datas.map<Contacts>((json) {
return Contacts.fromJson(json);
}).toList();
print(contacts);
return contacts;
} else {
return contacts = [];
}
}
this is view class
FutureBuilder<List<Contacts>>(
future: controller.c,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: (context, index) {
return Card(
child: CheckboxListTile(
title: Text(
snapshot.data![index].name ?? "name"),
value: controller.isChecked[index],
onChanged: (val) {
setState(
() {
print(snapshot.data![index]);
controller.selectContact(
index, val, snapshot.data![index]);
},
);
},
),
);
},
);
}
}),
anyone, please help me to filter the records from the snapshot data.
I successfully implemented it in listview but not in listviewBuildr

Related

Fetch data user with DIO API

I've been learning for days about him. But I still can't display it on screen. Maybe anyone can help ? please check it. i want to get some user data on my screen with Dio Package
in this dio client i try tu generalize every request in 1 .dart
Dio_Client.dart
import 'package:dio/dio.dart';
import 'package:latihan_dio/dio_interceptor.dart';
import '../../../../dio_client.dart';
import '/src/features/home/domain/user.dart';
enum RequestType { GET, POST, PUT, PATCH, DELETE }
class DioClient {
final dio = createDio();
DioClient._internal();
static final _singleton = DioClient._internal();
factory DioClient() => _singleton;
static Dio createDio() {
var dio = Dio(BaseOptions(
baseUrl: "https://reqres.in/api/users?page=2",
receiveTimeout: 20000, // 20 seconds
connectTimeout: 20000,
sendTimeout: 20000,
));
// dio.interceptors.addAll({
// AuthInterceptor(dio),
// });
// dio.interceptors.addAll({
// Logging(dio),
// });
return dio;
}
Future<Response<dynamic>> apiCall({
required String url,
required RequestType requestType,
Map<String, dynamic>? queryParameters,
Map<String, dynamic>? body,
Map<String, String>? header,
RequestOptions? requestOptions,
}) async {
late Response result;
// try {
switch (requestType) {
case RequestType.GET:
{
Options options = Options(headers: header);
result = await dio.get(url,
queryParameters: queryParameters, options: options);
break;
}
case RequestType.POST:
{
Options options = Options(headers: header);
result = await dio.post(url, data: body, options: options);
break;
}
case RequestType.DELETE:
{
Options options = Options(headers: header);
result =
await dio.delete(url, data: queryParameters, options: options);
break;
}
case RequestType.PUT:
{
Options options = Options(headers: header);
result = await dio.put(url, data: body, options: options);
break;
}
case RequestType.PATCH:
{
Options options = Options(headers: header);
result = await dio.patch(url, data: body, options: options);
break;
}
}
return result;
// if(result != null) {
// // return NetworkResponse.success(result.data);
// // } else {
// // return const NetworkResponse.error("Data is null");
// // }
// // }on DioError catch (error) {
// // return NetworkResponse.error(error.message);
// // } catch (error) {
// // return NetworkResponse.error(error.toString());
}
}
// }**
in this home screen i try to call api wit fetch user
home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:latihan_dio/src/features/home/domain/user.dart';
import '../../../../dio_client.dart';
class myHomepage extends StatefulWidget {
const myHomepage({Key? key}) : super(key: key);
#override
State<myHomepage> createState() => _myHomepageState();
}
class _myHomepageState extends State<myHomepage> {
List<User> users = [];
var selectedIndex = 0;
#override
void initState() {
super.initState();
fetchData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
child: Column(
children: [
ListView.builder(
// padding: EdgeInsets.symmetric(vertical: 16.5),
// scrollDirection: Axis.horizontal,
itemCount: users.length,
itemBuilder: (context, index) {
return Center(
child: Center(
child: Text(
'[data]${users[index]}',
style: TextStyle(
fontSize: 100,
color: Colors.red,
),
)),
);
},
),
// Text('data2'),
// Text('data3'),
// Text('data4'),
],
),
),
TextButton(
onPressed: () {},
child: Text(
'GET',
style: TextStyle(
fontSize: 100,
),
),
),
],
),
);
}
}
Future<void> fetchData() async {
var Response = await DioClient().apiCall(
url: 'https://reqres.in/api/users?page=2',
requestType: RequestType.GET,
// queryParameters: {},
);
List<dynamic> listUser = Response.data['result'];
List<User> users = listUser.map((e) => User.fromJson(e)).toList();
}
user.dart iam using freezed package for models,
// To parse this JSON data, do
//
// final user = userFromMap(jsonString);
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:convert';
part 'user.freezed.dart';
part 'user.g.dart';
#freezed
abstract class User with _$User {
const factory User({
#JsonKey(name: 'id') int? id,
#JsonKey(name: 'email') String? email,
#JsonKey(name: 'first_name') String? firstName,
#JsonKey(name: 'last_name') String? lastName,
#JsonKey(name: 'avatar') String? avatar,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
Instead of call async in initState, use FutureBuilder and you not checking the response to be success and also your get your list by calling Response.data['result'] instead of Response.data['data'] .Do like this:
Future<List<User?>> fetchData() async {
var Response = await DioClient().apiCall(
url: 'https://reqres.in/api/users?page=2',
requestType: RequestType.GET,
// queryParameters: {},
);
if (Response.statusCode == 200) {
List<dynamic> listUser = Response.data['data'];
List<User> users = listUser.map((e) => User.fromJson(e)).toList();
return users;
} else {
return [];
}
}
then use it like this:
Center(
child: FutureBuilder<List<User?>>(
future: fetchData(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<User?> data = snapshot.data ?? [];
return ListView.builder(
itemBuilder: (context, index) {
return Column(children: [
Text(data[index]?.firstName?? ''),
]);
},
itemCount: data.length,
);
}
}
},
),
)
try this
Future<void> fetchData() async {
var Response = await DioClient().apiCall(
url: 'https://reqres.in/api/users?page=2',
requestType: RequestType.GET,
// queryParameters: {},
);
List<dynamic> listUser = Response.data['result'];
users = listUser.map((e) => User.fromJson(e)).toList();
}
//remove reinit of userslist
Future<void> fetchData() async {
var Response = await DioClient().apiCall(
url: 'https://reqres.in/api/users?page=2',
requestType: RequestType.GET,
// queryParameters: {},
);
List<dynamic> listUser = Response.data;
// OR
List<dynamic> listUser = Response.data['data]; // if you want to acces s data inside it
List<User> users = listUser.map((e) => User.fromJson(e)).toList();
}
Try this

How to access an item from a json through FutureBuilder?

i'm getting a json and would like to access certain items.
The method below returns the json I need to access.
search(cpf) async {
try {
final response = await http.get(
Uri.parse(BaseUrl.baseUrl + 'api/produtor/serach/$data'));
if (response.statusCode == 200) {
final jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
final user = User.fromJson(jsonMap);
return user;
} else {
throw Exception("Error");
}
} catch (e) {
throw Exception(e.toString());
}
}
I created this example to try to access the items.
Future? _list;
#override
void initState() {
super.initState();
_list = widget.produtorServices.buscaProdutorPorCPF("56039891653");
}
Widget build(BuildContext context) {
return new Scaffold(
body: Container(
child: FutureBuilder(
future: widget.produtorServices.buscaProdutorPorCPF("56039891653"),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Text("${snapshot.error}");
}
if (!snapshot.hasData) {
return Text("Null returned");
}
final user = snapshot.data as Produtor;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('${user.id}: ${user.name}'),
],
); //Text(snapshot.data!.ip);
},
),
),
);
}
}
Here is json
[
{
"user":{
"roles":[
"622f533b5ee724631428f469"
],
"_id":"622f78fbf297571510cb4e32",
"nome":"XXXX",
"email":"teste#teste.com"
}
}
]
How do I add eg a text widget and access the json item?
I've already tried to solve using the model too. I declare User user and then I try to access the variable like this: user.name
But I get the error:
Error: Exception: Expected a value of type 'Map<String, dynamic>', but got one of type 'List'
I appreciate if anyone can help me analyze this!
You create two data classes to hold your JSON object.
class Users {
List<User> users;
Users({
required this.users,
});
factory Users.fromJson(Map<String, dynamic> json) => Users(
users: (json['users'] as List<dynamic>)
.map((e) => User.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
class User {
List<String>? roles;
String? id;
String? nome;
String? email;
User({
this.roles,
this.id,
this.nome,
this.email,
});
factory User.fromJson(Map<String, dynamic> json) => User(
roles: (json['roles'] as List<dynamic>?)?.map((e) =>
e as String).toList(),
id: json['id'] as String?,
nome: json['nome'] as String?,
email: json['email'] as String?,
);
}
Then in your search method:
if (response.statusCode == 200) {
final jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
final users = Users.fromJson(jsonMap);
return users;
} else {
throw Exception("Error");
}
In your FutureBuilder:
if (snapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Text("${snapshot.error}");
}
if (!snapshot.hasData) {
return Text("Null returned");
}
final userList = snapshot.data as Users;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: List<Text>.generate(
userList.users.length,
(index) {
final user = userList.users[index];
return Text('${user.id}: ${user.nome}, ${user.email}, ${user.roles}');
},
),
); //Text(snapshot.data!.ip);

Why I can't fetch data by Json on my Flutter App

I wasn't get any data from fake Api : https://jsonplaceholder.typicode.com/users to my flutter App. Can anyone please give me piece of advise why or how I can get those data on my app. For creating the Model file using https://app.quicktype.io/.
JsonModel File:
import 'dart:convert';
List<JsonModel> jsonModelFromJson(String str) =>
List<JsonModel>.from(json.decode(str).map((x) => JsonModel.fromJson(x)));
String jsonModelToJson(List<JsonModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class JsonModel {
JsonModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
int? id;
String? name;
String? username;
String? email;
Address? address;
String? phone;
String? website;
Company? company;
factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address?.toJson(),
"phone": phone,
"website": website,
"company": company?.toJson(),
};
}
class Address {
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
String? street;
String? suite;
String? city;
String? zipcode;
Geo? geo;
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo?.toJson(),
};
}
class Geo {
Geo({
this.lat,
this.lng,
});
String? lat;
String? lng;
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
Company({
this.name,
this.catchPhrase,
this.bs,
});
String? name;
String? catchPhrase;
String? bs;
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
Service or JsonApi File:
import 'dart:convert';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
class JsonApi {
bool loading = true;
var json_Data;
Future<JsonModel> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
var jsonModel = null;
try {
if (response.statusCode == 200) {
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
print(jsonModel);
} else {
throw Exception("falied to load");
}
} catch (Exception) {
return jsonModel;
}
return jsonModel;
}
}
Try to call it but As progress bar not closed it mean I didn't get the data
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:flutter_learning_from_pageview/Service/JsonApi.dart';
class JsonData extends StatefulWidget {
const JsonData({Key? key}) : super(key: key);
#override
_JsonDataState createState() => _JsonDataState();
}
class _JsonDataState extends State<JsonData> {
bool loading = true;
Future<JsonModel>? _jsonModel;
#override
void initState() {
_jsonModel = JsonApi().getJsonData();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _jsonModel,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(""),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}
You made some mistake so try to change it to like this. you are trying to parse list of data with just a single element.
class JsonApi {
Future<List<JsonModel>> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
if (response.statusCode == 200) {
return jsonModelFromJson(response.body);
} else {
throw Exception("falied to load");
}
}
}
Then try this code
late final Future<List<JsonModel>> _futureData;
apiCalling() {
_futureData = JsonApi().getJsonData();
}
#override
void initState() {
apiCalling();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot<List<JsonModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () {
setState(() {});
},
title: Text(snapshot.data![index].name!),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
from init state you have to change like this:
#override
void initState() {
callApi();
super.initState();
}
void callApi() async {
_jsonModel = await JsonApi().getJsonData();
}
as you are not calling that with await so, it has no data
I found your issue. You trying to fetch data in wrong jsonModel.
Remove this code
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
Use this Instead
jsonModel = jsonModelFromJson(response.body);
Your Api data is in Array format and you are trying to store in Class format.
Try below code hope its help to you.
Your API Call:
Future<List<dynamic>> getJobsData() async {
String url = 'https://jsonplaceholder.typicode.com/users';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body);
}
Your Widget:
Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
shrinkWrap: true,
physics:const NeverScrollableScrollPhysics(),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var id = snapshot.data![index]['id'];
var name = snapshot.data![index]['name'];
var username = snapshot.data![index]['username'];
var email = snapshot.data![index]['email'];
var phone = snapshot.data![index]['phone'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(id.toString()),
title: Text(name),
subtitle: Text(
username + '\n' + email + '\n' + phone.toString(),
),
),
);
},
),
);
}
return const CircularProgressIndicator();
},
),
),
Refer my answer here and here for get data from json API
Your Result Screen->
Make sure response.body is returning data.
Avoid using ? in futures, otherwise snapshot could be empty the whole time when body is null. The ui will always show loading.
To make your code look more simple:
Inside statefull widget:
late final Future<List<Data>> _futureData;
And in your initState:
#override
void initState(){
_futureData = provider.loadFutureData();
super.initState();
}
Or if you don't are using provider:
#override
void initState(){
_futureData = loadDataFromFunction();
super.initState();
}

Searchable Dropdown with Flutter, Mobx and Sqlite

I am tryng implement a Searchable Dropdown package:
https://github.com/salim-lachdhaf/searchable_dropdown
I am using mobx and Sqlite
See Widget Code:
DropdownSearch<TarefaModel>(
label: 'BUSCAR TAREFAS',
onFind: (String filter) =>
controller.filtrarTarefas(filter),
onChanged: (TarefaModel data) {
print(data);
},
dropdownBuilder: _customDropDownExample,
),
My Mobx action:
Controller action:
#observable
ObservableList<TarefaModel> tarefas = new ObservableList<TarefaModel>();
#action
filtrarTarefas(termo) async {
final repository = new TarefaRepository();
tarefas = new ObservableList<TarefaModel>();
var data = await repository.search(termo);
tarefas.addAll(data);
return tarefas;
}
Custom DropDown:
Widget _customDropDownExample(
BuildContext context, TarefaModel item, String itemDesignation) {
return Container(
child: Observer(
builder: (_) => ListView.builder(
itemCount: controller.tarefas.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(item.descricao),
subtitle: Text(item.label),
);
})),
);
}
My Model:
class TarefaModel{
int id;
String descricao;
TarefaModel({this.id, this.descricao});
Map<String, dynamic> toMap() {
return {'id': id,'descricao': descricao};
}
}
But this erros is show:
Any idea? Thanks
My repository:
Future<List<TarefaModel>> search(String term) async {
try {
final Database db = await _getDatabase();
final List<Map<String, dynamic>> maps = await db.query(
TAREFAS_TABLE,
where: "descricao LIKE ?",
whereArgs: [
'%$term%',
],
);
return List.generate(
maps.length,
(i) {
return TarefaModel(
id: maps[i]['id'],
descricao: maps[i]['descricao'],
);
},
);
} catch (ex) {
print(ex);
return new List<TarefaModel>();
}
}

Flutter Http call List<t> always result Null in UI

I have try many sample in stack but still can`t get the idea which part i miss, the result in UI always display null, ..
here is the code i try :
class PointBallance {
String id, date, datetime, companyid, storecode, customercode, topup, amount, remark, cashier, invoice ;
PointBallance({this.id, this.date, this.datetime, this.companyid, this.storecode, this.customercode, this.topup, this.amount, this.remark, this.cashier, this.invoice});
factory PointBallance.fromJson(Map<String, dynamic> json) {
return PointBallance(
id: json['id'],
date: json['date'],
datetime: json['datetime'],
companyid: json['company_id'],
storecode: json['store_code'],
customercode: json['customer_code'],
topup: json['topup'],
amount: json['amount'],
remark: json['remark'],
cashier: json['cashier'],
invoice: json['invoice'],
);
}
}
the part for call http is here :
Future<List<PointBallance>> pointBal() async {
var url = 'http://someUrl';
var res = await http.get(url);
if(res.statusCode == 200) {
var dtpoint = json.decode(res.body);
print(dtpoint);
var bel = List<PointBallance>.from(dtpoint.map((i) => PointBallance.fromJson(i)));
return bel;
} else {
throw Exception(
"Request to $url failed with status ${res.statusCode}: ${res.body}"
);
}
}
and for screen to display data ..
class _PointScreenState extends State<PointScreen> {
Future<List<PointBallance>> _point;
AuthService _authService = new AuthService();
#override
void initState() {
_point = _authService.pointBal();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Point'),
),
body: FutureBuilder<List<PointBallance>>(
future: _point,
builder: (context, snapshot) {
if (snapshot.hasData) {
var dt = snapshot.data[0].id;
return Column(
children: <Widget>[
**Text('in the top $dt'),**
Expanded(
child: ListView.builder(
itemCount: snapshot.data.length,
itemBuilder:(BuildContext context, int index){
var hei = snapshot.data[index];
return **Text(hei.id != null ? hei.id : 'Cant get data')**;
}),
),
],
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return CircularProgressIndicator();
}),
);
}
}
in console i got result
print(dtpoint);
any guide to correctly display data result? because in console there is result.