Home > Blockchain >  Flutter Class has no instance getter 'length'
Flutter Class has no instance getter 'length'

Time:02-17

I'm trying to get my json model, i get an error at the conversion stage, as a result, the model is returned empty.

Class 'Products' has no instance getter 'length'. Receiver: Instance of 'Products' Tried calling: length

My json:

[{
        "id": "3",
        "buy_image": "/uploads/1.jpg",
        "win_image": "/uploads/2.jpg",
        "prize_image": "/uploads/product.jpg",
        "tickets": "150",
        "quantity": "150",
        "timer": "2022-01-24",
        "draw_date": "2022-01-26",
        "price": "1500",
        "delivery_price": "1500",
        "coupon": "RP-6367-7548",
        "homepage": "1",
        "sale": "1",
        "catalog": "0",
        "created_at": "2021-12-09 01:40:28",
        "updated_at": "2022-01-27 14:51:49",
        "translation": {
            "id": "5",
            "owner_id": "3",
            "language": "ru",
            "buy_title": "Ручка",
            "buy_body": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget lectus auctor, mollis turpis nec, mollis magna. Quisque suscipit tristique sollicitudin. In semper mauris eget suscipit bibendum. Sed sagittis eu lectus pellentesque porttitor. Morbi nec condimentum lectus. Fusce convallis, lorem at posuere finibus, dolor augue tempus purus, sagittis gravida magna tellus id massa. Pellentesque nec arcu rhoncus, auctor erat eu, bibendum magna. Suspendisse tristique nisl tristique, cursus risus eget, condimentum purus. Nullam ligula felis, imperdiet congue purus in, efficitur vehicula enim. Aliquam egestas accumsan finibus. Curabitur nec magna risus.</p>",
            "prize_body": "<p>Купите ручку и получите шанс выиграть этот приз</p>",
            "win_title": "iPhone 12 Pro Bundle",
            "win_body": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget lectus auctor, mollis turpis nec, mollis magna. Quisque suscipit tristique sollicitudin. In semper mauris eget suscipit bibendum. Sed sagittis eu lectus pellentesque porttitor. Morbi nec condimentum lectus. Fusce convallis, lorem at posuere finibus, dolor augue tempus purus, sagittis gravida magna tellus id massa. Pellentesque nec arcu rhoncus, auctor erat eu, bibendum magna. Suspendisse tristique nisl tristique, cursus risus eget, condimentum purus. Nullam ligula felis, imperdiet congue purus in, efficitur vehicula enim. Aliquam egestas accumsan finibus. Curabitur nec magna risus.</p>"
        }
    },
    {
        "id": "4",
        "buy_image": "/uploads/1.jpg",
        "win_image": "/uploads/image.jpg",
        "prize_image": "/uploads/image.jpg",
        "tickets": "40000",
        "quantity": null,
        "timer": "2022-01-29",
        "draw_date": "2022-01-29",
        "price": "3500",
        "delivery_price": "2",
        "coupon": "RP-2302-3713",
        "homepage": "1",
        "sale": "4",
        "catalog": "1",
        "created_at": "2022-01-19 15:42:23",
        "updated_at": "2022-01-20 23:20:12",
        "translation": {
            "id": "7",
            "owner_id": "4",
            "language": "ru",
            "buy_title": "Ручку",
            "buy_body": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget lectus auctor, mollis turpis nec, mollis magna. Quisque suscipit tristique sollicitudin. In semper mauris eget suscipit bibendum. Sed sagittis eu lectus pellentesque porttitor. Morbi nec condimentum lectus. Fusce convallis, lorem at posuere finibus, dolor augue tempus purus, sagittis gravida magna tellus id massa. Pellentesque nec arcu rhoncus, auctor erat eu, bibendum magna. Suspendisse tristique nisl tristique, cursus risus eget, condimentum purus. Nullam ligula felis, imperdiet congue purus in, efficitur vehicula enim. Aliquam egestas accumsan finibus. Curabitur nec magna risus.</p>",
            "prize_body": "<p>Купите Ручку и получите шанс поехать на Мальдивы!</p>",
            "win_title": "Мальдивы",
            "win_body": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget lectus auctor, mollis turpis nec, mollis magna. Quisque suscipit tristique sollicitudin. In semper mauris eget suscipit bibendum. Sed sagittis eu lectus pellentesque porttitor. Morbi nec condimentum lectus. Fusce convallis, lorem at posuere finibus, dolor augue tempus purus, sagittis gravida magna tellus id massa. Pellentesque nec arcu rhoncus, auctor erat eu, bibendum magna. Suspendisse tristique nisl tristique, cursus risus eget, condimentum purus. Nullam ligula felis, imperdiet congue purus in, efficitur vehicula enim. Aliquam egestas accumsan finibus. Curabitur nec magna risus.</p>"
        }
    }
]

Model:

class Products {
  String? id;
  String? buyImage;
  String? winImage;
  String? prizeImage;
  String? tickets;
  String? quantity;
  String? timer;
  String? drawDate;
  String? price;
  String? deliveryPrice;
  String? coupon;
  String? homepage;
  String? sale;
  String? catalog;
  String? createdAt;
  String? updatedAt;
  Translation? translation;

  Products(
      {this.id,
        this.buyImage,
        this.winImage,
        this.prizeImage,
        this.tickets,
        this.quantity,
        this.timer,
        this.drawDate,
        this.price,
        this.deliveryPrice,
        this.coupon,
        this.homepage,
        this.sale,
        this.catalog,
        this.createdAt,
        this.updatedAt,
        this.translation});

  Products.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    buyImage = json['buy_image'];
    winImage = json['win_image'];
    prizeImage = json['prize_image'];
    tickets = json['tickets'];
    quantity = json['quantity'];
    timer = json['timer'];
    drawDate = json['draw_date'];
    price = json['price'];
    deliveryPrice = json['delivery_price'];
    coupon = json['coupon'];
    homepage = json['homepage'];
    sale = json['sale'];
    catalog = json['catalog'];
    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['buy_image'] = this.buyImage;
    data['win_image'] = this.winImage;
    data['prize_image'] = this.prizeImage;
    data['tickets'] = this.tickets;
    data['quantity'] = this.quantity;
    data['timer'] = this.timer;
    data['draw_date'] = this.drawDate;
    data['price'] = this.price;
    data['delivery_price'] = this.deliveryPrice;
    data['coupon'] = this.coupon;
    data['homepage'] = this.homepage;
    data['sale'] = this.sale;
    data['catalog'] = this.catalog;
    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? buyTitle;
  String? buyBody;
  String? prizeBody;
  String? winTitle;
  String? winBody;

  Translation(
      {this.id,
        this.ownerId,
        this.language,
        this.buyTitle,
        this.buyBody,
        this.prizeBody,
        this.winTitle,
        this.winBody});

  Translation.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    ownerId = json['owner_id'];
    language = json['language'];
    buyTitle = json['buy_title'];
    buyBody = json['buy_body'];
    prizeBody = json['prize_body'];
    winTitle = json['win_title'];
    winBody = json['win_body'];
  }

  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['buy_title'] = this.buyTitle;
    data['buy_body'] = this.buyBody;
    data['prize_body'] = this.prizeBody;
    data['win_title'] = this.winTitle;
    data['win_body'] = this.winBody;
    return data;
  }
}

Prodiver:

class ProductsProvider extends ChangeNotifier {
  Future<Products> getProducts({
    int? homepage,
    int? sale,
    int? soldout,
    String? lang,
  }) async {
    var queryParams = {
      'homepage': homepage.toString(),
      'sale': sale.toString(),
      'soldout': soldout.toString(),
      'lang': lang.toString(),
    };
    var headers = {
      HttpHeaders.contentTypeHeader: 'application/json',
    };
    String queryString = Uri(queryParameters: queryParams).query;
    var requestUrl = "${AppStrings.api}get-products"   '?'   queryString;
    var response = await http.get(Uri.parse(requestUrl), headers: headers);
    if (response.statusCode == 200) {
      var data = json.decode(response.body);
      Products products = Products.fromJson(data[0]);
      return products;
    } else {
      throw Exception();
    }
  }
}

Trying fetch:

late Future fetchHomepageProducts;
void initState() {
    fetchHomepageProducts = Provider.of<ProductsProvider>(context, listen: false)
        .getProducts(homepage: 1, lang: translator.activeLanguageCode);
    super.initState();
}
SizedBox(
    width: MediaQuery.of(context).size.width,
    height: 400,
    child: FutureBuilder(
        future: fetchHomepageProducts,
        builder: (BuildContext context, AsyncSnapshot < dynamic > snapshot) {
            if (!snapshot.hasData) {
                return Center(child: CircularProgressIndicator());
            } else {
                print(snapshot.data.length);
                return ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                        return Stack(
                            children: [
                                Container(
                                    width: MediaQuery.of(context).size.width / 1.4,
                                    height: 340,
                                    margin: EdgeInsets.only(
                                        top: 21, right: 20),
                                    padding: EdgeInsets.all(20),
                                    decoration: new BoxDecoration(
                                        color: Colors.white,
                                        borderRadius: BorderRadius.circular(16),
                                        border: Border.all(
                                            width: 1.5,
                                            color: Color(0xFFF4F5F6)),
                                        boxShadow: [
                                            BoxShadow(
                                                color: Colors.grey.withOpacity(.3),
                                                blurRadius: 10.0,
                                                spreadRadius: 0.0,
                                                offset: Offset(
                                                    0.0,
                                                    // Move to right 10  horizontally
                                                    10.0, // Move to bottom 10 Vertically
                                                ),
                                            )
                                        ],
                                    ),
                                    child: Column(
                                        textBaseline: TextBaseline.alphabetic,
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        crossAxisAlignment: CrossAxisAlignment.baseline,
                                        children: [
                                            Text(
                                                'Выиграй',
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Color(0xFF1B1D1F),
                                                    fontSize: 15,
                                                    fontStyle: FontStyle.italic,
                                                    letterSpacing: 0.02,
                                                    fontWeight: FontWeight.w700),
                                            ),
                                            Text(
                                                '₽ ${snapshot.data[index].price}',
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Color(0xFF3B71FE),
                                                    fontSize: 17,
                                                    fontStyle: FontStyle.italic,
                                                    letterSpacing: 0.02,
                                                    fontWeight: FontWeight.w700),
                                            ),
                                            Image.asset(
                                                "assets/images/product1.jpg",
                                                fit: BoxFit.cover,
                                            ),
                                            Text(
                                                'Купите кепку Rosso и получите шанс выиграть этот приз',
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Color(0xFF1B1D1F),
                                                    fontSize: 13,
                                                    letterSpacing: 0.02,
                                                ),
                                            ),
                                        ],
                                    ),
                                ),
                                Positioned(
                                    top: 0,
                                    left: 0,
                                    right: 0,
                                    child: Column(
                                        children: [
                                            Text(
                                                '473 продано из  480',
                                                style: TextStyle(
                                                    color: Color(0xFF1B1D1F),
                                                    fontSize: 13,
                                                    letterSpacing: 0.02,
                                                ),
                                            ),
                                            Container(
                                                margin: EdgeInsets.only(
                                                    left: 15, right: 35, top: 5),
                                                height: 6,
                                                decoration: new BoxDecoration(
                                                    color: Color(0xFFF34C17),
                                                    borderRadius: BorderRadius
                                                    .circular(16),
                                                ),
                                            )
                                        ],
                                    ),
                                ),
                                Positioned(
                                    bottom: 20,
                                    left: 0,
                                    right: 0,
                                    child: Padding(
                                        padding: const EdgeInsets.symmetric(
                                                horizontal: 50),
                                            child: OutlinedButton(
                                                onPressed: null,
                                                style: OutlinedButton.styleFrom(
                                                    padding:
                                                    EdgeInsets.symmetric(
                                                        vertical: 16),
                                                    backgroundColor: Colors.white,
                                                    side: BorderSide(
                                                        width: 1.0,
                                                        color: Colors.black),
                                                    shape: RoundedRectangleBorder(
                                                        borderRadius:
                                                        BorderRadius.circular(24))),
                                                child: const Text(
                                                    "ХОЧУ",
                                                    style: TextStyle(
                                                        color: Color(0xFF101D27),
                                                        fontSize: 16,
                                                        letterSpacing: 0.02,
                                                        fontWeight: FontWeight.w700),
                                                ),
                                            ),
                                    )),
                            ],
                        );
                    }
                );
            }
        }
    ),
)

Tried to add an index Products products = Products.fromJson(data[0]), because my json start with 0 index, but it did not help.

What am i missing, why is the model empty?

CodePudding user response:

What you are doing:

var data = json.decode(response.body);

Change this to:

var data = json.decode(response.body) as Map<String, dynamic>;

now you can return data and use it.


  • Instead of returning the result, I prefer using notifyListener. Using notifyListener, I do not have to wait for the data. I can show my page & when the data comes, I can show the data.
  • Try to call the function from didChangeDependencies(). Do read this link for better understanding link

I believe this should help you. I would suggest reading more documents on Flutter or you can even try Maximilian Schwarzmüller's lecture on udemy.



TRY THIS ::

Provider page:

(somewhere on the top)
List<Products> _data = [];
List<Products> get data {
   return [..._data];
}



(in your code)
if (response.statusCode == 200) {
      List<Products> newData = json.decode(response.body) as Map<String, dynamic>;
      _data = newData;
      notifyListeners();  // this will update all the places where data is being used
    }

Trying fetch:

(somewhere on the top inside state)
List<Porducts> products = [];


(below build)
products = Provider.of<ProductsProvider>(context).data;    // once you get something in your data at ProductsProvider, it will update here.


(inside the code)
ListView.builder(
    itemCount: products.length,
    itemBuilder: (context, index) {
    return Stack( ... your code ...);

CodePudding user response:

If you see carefully your Json, you can see that the response is a list of Products, but the model you have is just one product. So you need to edit your model to support a list of Products.

Something like this:

class ProductsModel {
  List<Products> products;

  ProductsModel(
      { required this.products});


  factory ProductsModel.fromJson(List<dynamic> json) {
    var list = json as List;
    List<Products> productsList = list.map((i) => Product.fromJson(i)).toList();

    return ProductsModel(
        dias: productsList);
  }


}

Also, you have to add your models, just be carefull with model's name because your model has a plural name but is just one object (just one product).

And, in your provider you should change this:

var data = json.decode(response.body);
Products products = Products.fromJson(data[0]);

for this:

ProductsModel products = ProductsModel.fromJson(jsonDecode(response.body));
  • Related