I know this question has been asked, but I'll explain my problem and show you what I've tried.
So, I receive a response from an API, that looks exactly like this:
[
{
"id": 1,
"nome": "Macarrão",
"descricao": "Macarrão Parafuso 100g",
"preco": 10.23,
"imagem": "https://www.-------.com.br/ccstore/v1/images/?source=/file/v3396941523676425853/products/141618_0.jpg"
},
{
"id": 2,
"nome": "Nescau",
"descricao": "Achocolatado Nescau",
"preco": 5.23,
"imagem": "https://www.-------.com.br/ccstore/v1/images/?source=/file/v3396941523676425853/products/141618_0.jpg"
},
{
"id": 3,
"nome": "Toddynho",
"descricao": "Bedida láctea - Toddynho",
"preco": 2.48,
"imagem": "https://www.-------.com.br/ccstore/v1/images/?source=/file/v3396941523676425853/products/141618_0.jpg"
},
{
"id": 4,
"nome": "Toddynho",
"descricao": "Bedida láctea - Toddynho",
"preco": 2.48,
"imagem": "https://www.-----.com.br/ccstore/v1/images/?source=/file/v3396941523676425853/products/141618_0.jpg"
}
]
Those are products that have 5 attributes, and I want to display them(the products) on screen. Right now my code looks like this:
Future<void> loadProducts() async {
final response = await http.get(Uri.parse(_url));
if (response.body == null) return;
Map<String, dynamic> data = jsonDecode(response.body);
print(response.body);
data.forEach((productId, productData) {
_items.add(
Product(
id: productId,
nome: productData['nome'],
descricao: productData['descricao'],
preco: productData['preco'],
imagem: productData['imagem'],
),
);
});
notifyListeners();
}
Product is
class Product with ChangeNotifier {
final String id;
final String nome;
final String descricao;
final double preco;
final String imagem;
bool isFavorite;
Product({
required this.id,
required this.nome,
required this.descricao,
required this.preco,
required this.imagem,
this.isFavorite = false,
});
void toggleFavorite() {
isFavorite = !isFavorite;
notifyListeners();
}
}
and I have tried solutions like this:
List<String> respApi =
(jsonDecode(response.body) as List<dynamic>).cast<String>();
from this answer , or this one
var usersDataFromJson = parsedJson['data'];
List<String> userData = List<String>.from(usersDataFromJson);
that would result in the error The argument type 'void Function(String, dynamic)' can't be assigned to the parameter type 'void Function(String)'
.
Thanks again for your help.
CodePudding user response:
If you look at your json, you see it's a List of Map, but on this line
Map<String, dynamic> data = jsonDecode(response.body);
you are putting it inside a Map so it's logic to get an error. So, to resolve the error, do this
List<Map> data = jsonDecode(response.body); //or List<Map<String, dynamic>> data = ...
but if it throws TypeError, do this instead
List data = jsonDecode(response.body);
And you can access your data like this
for(var element in data) {
element.forEach((k,v) {
//operations
}) ;
}
CodePudding user response:
I think you get the error on the line _items.add
. So based on te code in my previous answer it should be like this
_items.add(
Product(
id: element['id'] ,
nome: element['nome'],
descricao: element['descricao'],
preco: element['preco'],
imagem: element['imagem'],
)
)
and you don't need to use forEach
anymore. Also for your Product
class I advice you declare id
of type int
instead of String
to avoid errors since in your json id is an int.