After i changed the structure of my json i try to create a model, i get an error:
NoSuchMethodError (NoSuchMethodError: Class 'Translation' has no instance method 'map'. Receiver: Instance of 'Translation' Tried calling: map(Closure: (dynamic) => Carousel))
My json response
[{
"id": "1",
"position": "1",
"created_at": "2021-12-20 12:10:58",
"updated_at": "2022-01-26 10:59:04",
"translation": {
"id": "1",
"owner_id": "1",
"language": "ru",
"title": "Top Banner 1",
"desktop": "/uploads/banners/banner.jpg",
"mobile": "/uploads/banners/mobile-banner.jpg",
"url": "#"
}
},
{
"id": "2",
"position": "1",
"created_at": "2021-12-20 12:24:58",
"updated_at": "2022-01-12 13:26:09",
"translation": {
"id": "3",
"owner_id": "2",
"language": "ru",
"title": "Top Banner 2",
"desktop": "/uploads/banners/banner.jpg",
"mobile": "/uploads/banners/mobile-banner.jpg",
"url": "#"
}
},
{
"id": "3",
"position": "1",
"created_at": "2021-12-20 12:25:26",
"updated_at": "2022-01-12 15:33:38",
"translation": {
"id": "5",
"owner_id": "3",
"language": "ru",
"title": "Top Banner 3",
"desktop": "/uploads/banners/banner.jpg",
"mobile": "/uploads/banners/mobile-banner.jpg",
"url": "#"
}
},
{
"id": "4",
"position": "1",
"created_at": "2021-12-20 12:25:50",
"updated_at": "2022-01-17 09:04:48",
"translation": {
"id": "7",
"owner_id": "4",
"language": "ru",
"title": "Top Banner 4",
"desktop": "/uploads/banners/banner.jpg",
"mobile": "/uploads/banners/mobile-banner.jpg",
"url": "#"
}
},
{
"id": "5",
"position": "1",
"created_at": "2021-12-20 12:26:12",
"updated_at": "2022-01-17 09:05:03",
"translation": {
"id": "9",
"owner_id": "5",
"language": "ru",
"title": "Top Banner 5",
"desktop": "/uploads/banners/banner.jpg",
"mobile": "/uploads/banners/mobile-banner.jpg",
"url": "#"
}
}
]
My model:
class Banners {
String? id;
String? position;
String? createdAt;
String? updatedAt;
Translation? translation;
Banners(
{this.id,
this.position,
this.createdAt,
this.updatedAt,
this.translation});
Banners.fromJson(Map<String, dynamic> json) {
id = json['id'];
position = json['position'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
translation = json['translation'] != null
? new Translation.fromJson(json['translation'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['position'] = this.position;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
if (this.translation != null) {
data['translation'] = this.translation!.toJson();
}
return data;
}
}
class Translation {
String? id;
String? ownerId;
String? language;
String? title;
String? desktop;
String? mobile;
String? url;
Translation(
{this.id,
this.ownerId,
this.language,
this.title,
this.desktop,
this.mobile,
this.url});
Translation.fromJson(Map<String, dynamic> json) {
id = json['id'];
ownerId = json['owner_id'];
language = json['language'];
title = json['title'];
desktop = json['desktop'];
mobile = json['mobile'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['owner_id'] = this.ownerId;
data['language'] = this.language;
data['title'] = this.title;
data['desktop'] = this.desktop;
data['mobile'] = this.mobile;
data['url'] = this.url;
return data;
}
}
My provider:
class BannersProvider extends ChangeNotifier {
Future<Translation?> getBanners({
int? position,
String? lang,
}) async {
var queryParams = {
'position': position.toString(),
'lang': lang.toString(),
};
var headers = {
HttpHeaders.contentTypeHeader: 'application/json',
};
String queryString = Uri(queryParameters: queryParams).query;
var requestUrl = "${AppStrings.api}get-banners" '?' queryString;
var response = await http.get(Uri.parse(requestUrl), headers: headers);
if (response.statusCode == 200) {
var data = json.decode(response.body);
Translation? banners = Banners.fromJson(data[0]).translation;
return banners;
} else {
throw Exception();
}
}
}
FutureBuilder:
FutureBuilder(
future: fetchTopBanners,
builder:
(BuildContext context, AsyncSnapshot < dynamic > snapshot) =>
Column(
children: [
if (snapshot.hasData)
CarouselSlider(
options: CarouselOptions(
autoPlay: true,
aspectRatio: 2.0,
enlargeCenterPage: true,
),
items: snapshot.data
.map < Widget > ((item) => Carousel(item))
.toList())
else
Center(
child: CircularProgressIndicator(),
)
],
)),
My Homepage:
class _HomeState extends State<Home> {
late Future fetchTopBanners;
void initState() {
fetchTopBanners = Provider.of<BannersProvider>(context, listen: false)
.getBanners(position: 1, lang: translator.activeLanguageCode);
super.initState();
}
}
I realized that the problem occurs at the json conversion stage, so I added Banners.fromJson(data[0]).translation to the provider, where [0] is the root branch.
How can i solve this problem?
CodePudding user response:
As i can see your json you have list of Banners so you can use CarouselSlider.builder method to achieve slider like this.
CarouselSlider.builder(
itemCount: banners.length,
options: CarouselOptions(
viewportFraction: 1,
autoPlay: false,
itemBuilder:
(BuildContext context, int itemIndex, int pageViewIndex) {
return Image.network(banner[index].translation.desktop)
},
),
CodePudding user response:
Seeing that there's only a .map
method the code you posted, I'd say that the issue lies there, in the snapshot.data.map<Widget>(...etc...)
. My wild guess here is that you expect snapshot.data
to be a List
, or an Iterable
, while at runtime it turns out to be a Translation
(whatever it may be). Do some debugging and see what type it is, and check the return type of fetchTopBanners
.
Also, it might be a good idea to check the connectionState
of snapshot
before trying to access its .data
, just in case.