Home > Net >  NoSuchMethodError: Class has no instance method 'map'
NoSuchMethodError: Class has no instance method 'map'

Time:02-15

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.

  • Related