Danny
Danny

Reputation: 327

Flutter: Dart Error: RangeError (index): Invalid value: Only valid value is 0: 1

Hey guys I am new to Flutter and trying to build a variation selector for an eCommerce application. I am getting this error while trying to build a size variation widget for the size-color variation. It works for size only or color only variation. This is the error RangeError (index): Invalid value: Only valid value is 0: 1.

Also, when I print the length of the array, I am getting the value 1.

The idea is to show the available sizes when someone clicks on a color that gets displayed without any issues. but while trying to show the size, facing this error.

This is the code

///size widget
class SelectSizeWidget extends StatefulWidget {
  SelectSizeWidget({
    Key? key,
  }) : super(key: key);

  @override
  _SelectSizeWidgetState createState() => _SelectSizeWidgetState();
}

class _SelectSizeWidgetState extends State<SelectSizeWidget> {
  @override
  Widget build(BuildContext context) {
    return Consumer<ProductController>(
      builder: (_,model,__) {
        return Wrap(
          spacing: 8,
          runSpacing: 8,
          children: List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {
            if(model.sizeColour.isNotEmpty) {
              if(model.selectedColour != null || model.selectedColour != ""){
              var _res = model.sizeColour
                  .where((element) =>
                      element.var2!.toUpperCase() == model.selectedColour)
                  .toList();
              var _size = _res[index];
              return buildSize(_size);

            } else {
                var _res = model.sizeColour.toList();
                var _size = _res[index];
                return buildSize(_size);

              }
          } else if (model.size.isNotEmpty) {
              var _size = model.size[index];
              return buildSize(_size);
            }else if(model.materialSize.isNotEmpty){
              var _res = model.materialSize.where((element) =>
              element.var1.toUpperCase() == model.selectedMaterial)
                  .toList();
              var _size = _res[index];
              return buildSize(_size);
            }else{
              return SizedBox.shrink();
            }
          }),
        );
      }
    );
  }

  SizedBox buildSize(Variant size) {
    return SizedBox(
      height: 38,
      child: RawChip(
        label: Text(size.var1),
        labelStyle: TextStyle(color: Theme.of(context).hintColor),
        padding: EdgeInsets.symmetric(horizontal: 7, vertical: 7),
        backgroundColor: Theme.of(context).focusColor.withOpacity(0.05),
        selectedColor: Theme.of(context).focusColor.withOpacity(0.2),
        selected: size.varId == context.read<ProductController>().selectedVariation,
        shape: StadiumBorder(side: BorderSide(color: Theme.of(context).focusColor.withOpacity(0.05))),
        onSelected: (bool value) {
          context.read<ProductController>().setSize(size.varId);
        },
      ),
    );
  }
}

Productcontroller - for detail

List<Variant> size = [];
List<Variant> colour = [];
List<Variant> sizeColour = [];
List<String> ss = [];
List<String> cc = [];


Future<bool> getProductDetails({required String slug}) async {

  final val = await ApiProvider().getProductDetails(slug: slug);
  if (val.statusCode == 200 || val.statusCode == 201) {
    product = productDetailsResponseFromJson(jsonEncode(val.data));

    /// variation
    if (product!.variants) {
      clearAll();
      List<Map<int, Set<String>>> sc = [];
      List<String> s = [];
      List<String> c = [];

      selectedVariation = product!.prdtVari.first.id;
      for (var each in product!.prdtVari) {
        var _var = each.variation.toLowerCase();
        
        if (_var == 'colour') {
          colour.add(Variant(
              varId: each.id,
              var1: each.variationTypes.first.name,
              typeMap1: each.variationTypes.first.typeMap));
          c.add(each.variationTypes.first.name);
          notifyListeners();
        } else if (_var == 'size') {
          size.add(Variant(
              varId: each.id,
              var1: each.variationTypes.first.name,
              typeMap1: each.variationTypes.first.typeMap));
          s.add(each.variationTypes.first.name);
          notifyListeners();
        } else if (_var == 'size-colour') {
          sc.add({
            each.id: {
              each.variationTypes.first.name,
              each.variationTypes.last.name
            }
          });
          sizeColour.add(Variant(
              varId: each.id,
              var1: each.variationTypes.first.name,
              typeMap1: each.variationTypes.first.typeMap,
              var2: each.variationTypes.last.name,
              typeMap2: each.variationTypes.last.typeMap));
          s.add(each.variationTypes.first.name);
          c.add(each.variationTypes.last.name);
          notifyListeners();
        } 
      }
      ss = s.toSet().toList();
      cc = c.toSet().toList();

      if(cc.isNotEmpty){
        if(product!.prdtVari.first.variation.toLowerCase() == "colour"){
          selectedColour = colour.where((element) => element.varId == selectedVariation!).first.var1.toUpperCase();
        } else if(product!.prdtVari.first.variation.toLowerCase() == "size-colour") {
          selectedColour = sizeColour.where((element) => element.varId == selectedVariation!).first.var2!.toUpperCase();
        }
      };
      notifyListeners();
    }
    isLoading = false;
    notifyListeners();
    return true;
  } else {
    isLoading = false;
    notifyListeners();
    return false;
  }
}

API model

// To parse this JSON data, do
//
//     final productDetailsResponse = productDetailsResponseFromJson(jsonString);

import 'dart:convert';

ProductDetailsResponse productDetailsResponseFromJson(String str) => ProductDetailsResponse.fromJson(json.decode(str));

String productDetailsResponseToJson(ProductDetailsResponse data) => json.encode(data.toJson());


class ProductDetailsResponse {
  ProductDetailsResponse({

    required this.category,
    required this.title,
    required this.variants,
    required this.slug,
    required this.averageReview,
    required this.countReview,
    required this.productDetailsInfo,
    required this.prdtImg,
    required this.prdtVari,
  });

  int category;
  String title;
  bool variants;
  String slug;
  double averageReview;
  int countReview;
  ProductDetailsInfo productDetailsInfo;
  List<ProductDetailsImages> prdtImg;
  List<ProductDetailsVariation> prdtVari;

  factory ProductDetailsResponse.fromJson(Map<String, dynamic> json) => ProductDetailsResponse(

    category: json["category"],
    title: json["title"],
    variants: json["var"],
    slug: json["slug"],
    averageReview: json["rating"],
    countReview: json["rCount"],
    productDetailsInfo: ProductDetailsInfo.fromJson(json["prdtInfo"]),
    prdtImg: List<ProductDetailsImages>.from(json["prdtImg"].map((x) => ProductDetailsImages.fromJson(x))),
    prdtVari: List<ProductDetailsVariation>.from(json["prdtVari"].map((x) => ProductDetailsVariation.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {

    "category": category,
    "title": title,
    "var": variants,
    "slug": slug,
    "rating": averageReview,
    "rCount": countReview,
    "prdtInfo": productDetailsInfo.toJson(),
    "prdtImg": List<dynamic>.from(prdtImg.map((x) => x.toJson())),
    "prdtVari": List<dynamic>.from(prdtVari.map((x) => x.toJson())),
  };
}

class ProductDetailsImages {
  ProductDetailsImages({
    required  this.id,
    required  this.images,
    required  this.cover,
  });

  int id;
  String? images;
  bool cover;

  factory ProductDetailsImages.fromJson(Map<String, dynamic> json) => ProductDetailsImages(
    id: json["id"],
    images: json["images"],
    cover: json["cover"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "images": images,
    "cover": cover,
  };
}

class ProductDetailsInfo {
  ProductDetailsInfo({
    required  this.brand,
    required  this.mrp,
    required  this.price,
    required  this.inStock,
    required  this.desc,
    required  this.shipCost,
    required  this.condition,
  });

  String? brand;
  double mrp;
  double price;
  String inStock;
  String desc;
  double? shipCost;
  String condition;

  factory ProductDetailsInfo.fromJson(Map<String, dynamic> json) => ProductDetailsInfo(

    brand: json["brd"],
    mrp: json["mrp"],
    price: json["price"],
    inStock: json["iStock"],
    desc: json["desc"],
    shipCost: json["shCost"],
    condition: json["con"],

  );

  Map<String, dynamic> toJson() => {
    "brand": brand,
    "mrp": mrp,
    "price": price,
    "iStock": inStock,
    "desc": desc,
    "shCost": shipCost,
    "con": condition,

  };
}

class ProductDetailsVariation {
  ProductDetailsVariation({
    required this.id,
    required this.variation,
    required this.mrp,
    required this.price,
    required this.inStock,
    required this.images,
    required this.variationTypes,
  });

  int id;
  String variation;
  double mrp;
  double price;
  String inStock;
  List<ProductDetailsImages> images;
  List<ProductDetailsVariationType> variationTypes;

  factory ProductDetailsVariation.fromJson(Map<String, dynamic> json) => ProductDetailsVariation(
    id: json["id"],
    variation: json["vAtion"],
    mrp: json["mrp"],
    price: json["price"],
    inStock: json["iStock"],
    images: List<ProductDetailsImages>.from(json["imgs"].map((x) => ProductDetailsImages.fromJson(x))),
    variationTypes: List<ProductDetailsVariationType>.from(json["vTypes"].map((x) => ProductDetailsVariationType.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "vAtion": variation,
    "mrp": mrp,
    "price": price,
    "iStock": inStock,
    "imgs": List<dynamic>.from(images.map((x) => x.toJson())),
    "vTypes": List<dynamic>.from(variationTypes.map((x) => x.toJson())),
  };
}

class ProductDetailsVariationType {
  ProductDetailsVariationType({
    required  this.id,
    required  this.name,
    required this.typeMap,
  });
  int id;
  String name;
  String typeMap;

  factory ProductDetailsVariationType.fromJson(Map<String, dynamic> json) => ProductDetailsVariationType(
    id: json["id"],
    name: json["name"],
    typeMap: json["tMap"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "name": name,
    "tMap": typeMap,
  };
}

Thanks

Upvotes: 0

Views: 2039

Answers (4)

Mohammed Fouad
Mohammed Fouad

Reputation: 98

I could not read all the code and test it, but I got that error before. When? for example,

    List<String> myList = [1 , 2 ,3 ,4];

child : ListView(
children: [
  Text("${mylist[0]}"),
  Text("${mylist[1]}"),
  Text("${mylist[2]}"),
  Text("${mylist[3]}"),
  Text("${mylist[4]}"),
]
) ;

so you have four items in the list which mean your index will be just until 3 if you add more than the items in the list it will show that error. I hope I was able to explain.

Upvotes: 0

belinda.g.freitas
belinda.g.freitas

Reputation: 1157

List.generate is using model.ss.length or model.size.length to generate your list like you instructed on this line

List.generate((model.sizeColour.isNotEmpty) ? model.ss.length : model.size.length , (index) {

It means index <= model.ss.length-1 or index <= model.size.length-1. Then you did

var _res = model.sizeColour.where((element) => element.var2!.toUpperCase() == model.selectedColour).toList();

So if var _size = _res[index] throw RangeError it means _res.length < model.ss.length-1 or _res.length < model.size.length-1 but it should be equal, so the solution is to make sure the 3 arrays have the same length.

Upvotes: 1

phankieuphu
phankieuphu

Reputation: 196

Error often happen when you render data in list but you hasn't data you try check null in code because you not have controller call api or data any where

  • you can check line code has "if" ...
  • check length of list > 0
  • "var _size = _res[index];" maybe index null

Upvotes: 0

Kaushik Chandru
Kaushik Chandru

Reputation: 17772

Try replacing the 'or' with 'and'

if(model.selectedColour != null && model.selectedColour != "")

Since you used or it is always true if either of the condition is met. So even it's empty that variable was assigned with empty value.

Upvotes: 0

Related Questions