I am trying to get data from an API
Here you have the API Call:
Future<List<Clinica>> fetchClinicas(String idUsuario) async {
print("USUARIO ID EN FETCHCLINICAS " idUsuario);
String url = Constantes().URLProyecto Constantes().APICarpeta "get_clinicas.php?usuario=" idUsuario;
final response = await http.get(Uri.parse(url));
print("RESPONSE BODY CLINICAS " response.body.toString());
return clinicaFromJson(response.body);
}
The output from the response.body is
I/flutter (13249): RESPONSE BODY CLINICAS [{"id_clinica":"9","nombre_clinica":"Centro de Fisioterapia de Pruebas Capenergy 2","direccion_clinica":"Avinguda Mare de D\u00e9u de Montserrat, 41Bis (Pasaje), 08970 Sant Joan Desp\u00ed, Barcelona, Espa\u00f1a","tel_clinica":"934774348","cod_clinica":"TEST-002","fecha_ingreso_clinica":"2019-05-15","visiblePacientes":"1","visibleAgenda":"0","visibleForo":"1","visibleSAT":"1","logo_clinica":"qT3cKFdescarga.png"}]
That means that the response is not empty.
Then I am trying to show the downloaded items on a ListView.builder, but the snapshot is empty.
Expanded(
child: Container(
child: FutureBuilder(
future: fetchClinicas(miId),
builder: (context, snapshot) {
print("SNAPSHOT " snapshot.hasData.toString());
if (snapshot.hasData) {
print("estoy en snapshot has data");
List<dynamic>? filteredList = snapshot.data as List?;
filteredList ??= [];
return ListView.builder(
itemCount: filteredList.length,
shrinkWrap: true,
itemBuilder: (BuildContext context, index) {
print(index.toString());
Clinica clinica = filteredList![index];
return new GestureDetector(
...
}
return Image.asset(
"assets/images/vacio.png",
fit: BoxFit.contain,
);
},
I am always getting as result the image.asset which is loading if snatshot has no data.
EDIT
Here you have Clinica model class:
import 'dart:convert';
List<Clinica> clinicaFromJson(String str) => List<Clinica>.from(json.decode(str).map((x) => Clinica.fromJson(x)));
String clinicaToJson(List<Clinica> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Clinica {
Clinica({
required this.idClinica,
required this.nombreClinica,
required this.direccionClinica,
required this.telClinica,
required this.emailClinica,
required this.codClinica,
required this.fechaIngresoClinica,
required this.logoClinica,
required this.visiblePacientes,
required this.visibleAgenda,
required this.visibleForo,
required this.visibleSAT
});
String idClinica;
String nombreClinica;
String direccionClinica;
String telClinica;
String emailClinica;
String codClinica;
DateTime fechaIngresoClinica;
String logoClinica;
String visiblePacientes;
String visibleAgenda;
String visibleForo;
String visibleSAT;
factory Clinica.fromJson(Map<String, dynamic> json) => Clinica(
idClinica: json["id_clinica"],
nombreClinica: json["nombre_clinica"],
direccionClinica: json["direccion_clinica"],
telClinica: json["tel_clinica"],
emailClinica: json["email_clinica"],
codClinica: json["cod_clinica"],
fechaIngresoClinica: DateTime.parse(json["fecha_ingreso_clinica"]),
logoClinica: json["logo_clinica"],
visiblePacientes: json["visiblePacientes"],
visibleAgenda: json["visibleAgenda"],
visibleForo: json["visibleForo"],
visibleSAT: json["visibleSAT"],
);
Map<String, dynamic> toJson() => {
"id_clinica": idClinica,
"nombre_clinica": nombreClinica,
"direccion_clinica": direccionClinica,
"tel_clinica": telClinica,
"email_clinica": emailClinica,
"cod_clinica": codClinica,
"fecha_ingreso_clinica": "${fechaIngresoClinica.year.toString().padLeft(4, '0')}-${fechaIngresoClinica.month.toString().padLeft(2, '0')}-${fechaIngresoClinica.day.toString().padLeft(2, '0')}",
"logo_clinica": logoClinica,
"visiblePacientes": visiblePacientes,
"visibleAgenda": visibleAgenda,
"visibleForo": visibleForo,
"visibleSAT": visibleSAT,
};
}
CodePudding user response:
Data doesn't have "email_clinica" while the model expects that. Mark it as optional.
...
String telClinica;
String? emailClinica;
String codClinica;
...
CodePudding user response:
Here I'm displaying a simple fetch of a list of posts and converting them to a list and displaying it in a ListView.builder
Api Service:
static Future<List<PostModel>> fetchPosts({
required int pageNum,
}) async {
var url = Config.apiUrl Config.postsUrl pageNum.toString();
// here we're fetching the data from the api
var response = await http.get(
Uri.parse(url),
);
// checking if the call is a success or not
if (response.statusCode == 200) {
// if yes then get the body from the response and fill the method
// where we convert the data to an actual list of a model in the
// PostsModel class
var jsonString = response.body;
return postsFromJson(jsonString);
} else {
List<PostModel> emptyList = [];
return emptyList;
}
}
PostsModel:
// here we are decoding the body of the response and converting
// to a list of that Model
List<PostModel> postsFromJson(String str) => List<PostModel>.from(
json.decode(str).map(
(x) => PostModel.fromJson(x),
),
);
class PostModel {
int? id;
String? title;
dynamic imageUrl;
String? postedDate;
String? author;
String? postContent;
PostModel({
required this.id,
required this.title,
required this.imageUrl,
required this.postedDate,
required this.author,
required this.postContent,
});
// here we can find the fromJson method which converts the json into
// a dart objcet which in my case here is a PostModel
PostModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title']['rendered'];
imageUrl = json["_embedded"]["wp:featuredmedia"] == null
? 'https://pergjigje.net/wp-content/uploads/2021/09/Logo-e-544.png'
: json["_embedded"]["wp:featuredmedia"][0]["source_url"];
postedDate = DateFormat('MMMM d, yyyy').format(
DateTime.parse(
json['date'],
),
);
author = json["_embedded"]["author"][0]["name"];
if (json['content']['rendered'] != null) {
postContent = json['content']['rendered'];
}
}
PostModel.searchFromJson(
Map<String, dynamic> json, Map<String, dynamic> searchMediaJson) {
id = json['id'];
title = json['title']['rendered'];
imageUrl = searchMediaJson['source_url'] == null
? 'https://via.placeholder.com/300x150.png'
: json['source_url'];
postedDate = DateFormat('MMMM d, yyyy').format(
DateTime.parse(
json['date'],
),
);
author = json["_embedded"]["author"][0]["name"];
if (json['content']['rendered'] != null) {
postContent = json['content']['rendered'];
}
}
}
My postsController(Because I use GetX as a state manager):
// In the controller we call the method which we created in the
//services and fill a local list with its result
// you can call this in the **initState()** btw or put it in a
//**FutureBuilder()**
Future<void> fetchPosts({
int? pageNum = 0,
}) async {
try {
if (postsList.isEmpty || pageNum == 0) {
isLoading(true);
postsList.clear();
}
var posts = await ApiServices.fetchPosts(
pageNum: pageNum!.toInt(),
);
if (posts.isNotEmpty) {
_page = 5;
// Here we are filling the local postsList with the list from the
//apiService
postsList.assignAll(posts);
}
} finally {
isLoading(false);
}
}
Listview.builder:
child: ListView.builder(
// Here we are giving the length of the local list we filled in the
//controller
itemCount: postsController.postsList.length,
shrinkWrap: true,
controller: _postsController.scrollController,
itemBuilder: (context, index) {
// And finally we are using the data from the list to display in the screen
var data = postsController.postsList[index];
if (index == postsController.postsList.length - 1) {
return const Padding(
padding: EdgeInsets.all(10.0),
child: CostumeProgressIndicator(),
);
} else {
return PostItemWidget(
data: data,
index: index,
);
}
},
),