在 Flutter 中,我如何使用 API 和 GetX 在 JASON 中获取数据

时间:2021-03-19 18:03:31

标签: api rest flutter http get

在 Flutter 中,我尝试过这种方式,但没有任何输出。我想从包含 JASON 数据的 URL 获取数据,并根据名称、价格、图像等获取所有数据。但我无法使用以下方法。代码有什么问题。谁能帮我?谢谢。

这是我的product_model.dart文件

// To parse this JSON data, do
//
//     final product = productFromJson(jsonString);

import 'dart:convert';

Product productFromJson(String str) => Product.fromJson(json.decode(str));

String productToJson(Product data) => json.encode(data.toJson());

class Product {
    Product({
        this.code,
        this.meta,
        this.data,
    });

    int code;
    Meta meta;
    List<Datum> data;

    factory Product.fromJson(Map<String, dynamic> json) => Product(
        code: json["code"],
        meta: Meta.fromJson(json["meta"]),
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "code": code,
        "meta": meta.toJson(),
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
    };
}

class Datum {
    Datum({
        this.id,
        this.name,
        this.description,
        this.image,
        this.price,
        this.discountAmount,
        this.status,
        this.categories,
    });

    int id;
    String name;
    String description;
    String image;
    String price;
    String discountAmount;
    bool status;
    List<Category> categories;

    factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        id: json["id"],
        name: json["name"],
        description: json["description"],
        image: json["image"],
        price: json["price"],
        discountAmount: json["discount_amount"],
        status: json["status"],
        categories: List<Category>.from(json["categories"].map((x) => Category.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "description": description,
        "image": image,
        "price": price,
        "discount_amount": discountAmount,
        "status": status,
        "categories": List<dynamic>.from(categories.map((x) => x.toJson())),
    };
}

class Category {
    Category({
        this.id,
        this.name,
    });

    int id;
    String name;

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

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

class Meta {
    Meta({
        this.pagination,
    });

    Pagination pagination;

    factory Meta.fromJson(Map<String, dynamic> json) => Meta(
        pagination: Pagination.fromJson(json["pagination"]),
    );

    Map<String, dynamic> toJson() => {
        "pagination": pagination.toJson(),
    };
}

class Pagination {
    Pagination({
        this.total,
        this.pages,
        this.page,
        this.limit,
    });

    int total;
    int pages;
    int page;
    int limit;

    factory Pagination.fromJson(Map<String, dynamic> json) => Pagination(
        total: json["total"],
        pages: json["pages"],
        page: json["page"],
        limit: json["limit"],
    );

    Map<String, dynamic> toJson() => {
        "total": total,
        "pages": pages,
        "page": page,
        "limit": limit,
    };
}

这是我的api_service.dart文件

import 'package:http/http.dart' as http;
import 'package:mashmart/models/product_model.dart';

class ApiService {
  static var client = http.Client();

  static Future<List<Product>> fetchProducts() async {
    var url = Uri.https(
        'https://gorest.co.in', '/public-api/products');
    var response = await client.get(url);

    if (response.statusCode == 200) {
      var jasonString = response.body;
      return productFromJson(jasonString);
    } else {
      print('Request failed with status: ${response.statusCode}.');
      return null;
    }
  }
}

这是我的product_controller.dart文件

import 'package:get/state_manager.dart';
import 'package:mashmart/models/product_model.dart';
import 'package:mashmart/services/api_service.dart';

class ProductController extends GetxController {
  var isLoading = true.obs;
  var productList = List<Product>().obs;

  @override
  void onInit() {
    fetchProducts();
    super.onInit();
  }

  void fetchProducts() async {
    try{
      isLoading(true);
      var products = await ApiService.fetchProducts();
      if(products != null){
        productList.value = products;
      }
    } finally {
      isLoading(false);
    }
  }
}

这是我的homepage.dart文件

import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:get/get.dart';
import 'package:mashmart/controllers/product_controller.dart';
import 'package:mashmart/services/api_service.dart';
import 'package:mashmart/views/products/product_tile.dart';

class HomePage extends StatelessWidget {
  final GlobalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();

  final ProductController productController = Get.put(ProductController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      drawer: Drawer(),
      appBar: AppBar(
        title: Text(
          "Category",
          style: TextStyle(color: Colors.black87),
        ),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.grey[100],
        leading: IconButton(
          icon: Icon(Icons.menu_rounded),
          color: Colors.black87,
          onPressed: () {
            print("Drawer Menu Clicked");
            _key.currentState.openDrawer();
          },
        ),
        actions: <Widget>[
          Stack(
            children: [
              IconButton(
                  icon: Icon(
                    Icons.shopping_cart,
                    size: 30,
                    color: Colors.black87,
                  ),
                  onPressed: () {
                    print("Cart Clicked");
                  }),
              Positioned(
                top: 20,
                right: 4,
                child: Container(
                  height: 22,
                  width: 22,
                  padding: EdgeInsets.all(4),
                  decoration: BoxDecoration(
                      shape: BoxShape.circle, color: Colors.deepPurple),
                  child: Center(
                    child: Text(
                      "0",
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                  ),
                ),
              ),
            ],
          ),
          Stack(
            children: [
              IconButton(
                  icon: Icon(
                    Icons.notifications_rounded,
                    size: 30,
                    color: Colors.black87,
                  ),
                  onPressed: () {
                    print("Notifications Clicked");
                  }),
              Positioned(
                top: 20,
                right: 4,
                child: Container(
                  height: 22,
                  width: 22,
                  padding: EdgeInsets.all(4),
                  decoration: BoxDecoration(
                      shape: BoxShape.circle, color: Colors.deepPurple),
                  child: Center(
                    child: Text(
                      "0",
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Expanded(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      TextFormField(
                        decoration: InputDecoration(
                            hintText: "Search for markets or products",
                            prefixIcon: Icon(Icons.search_rounded),
                            border: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(10),
                            )),
                        onTap: () {
                          print("Search Box Tapped");
                        },
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Expanded(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Text(
                            "Products",
                            style: TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                                color: Colors.black87),
                          ),
                          Row(
                            children: [
                              IconButton(
                                  icon: Icon(
                                    Icons.list_rounded,
                                    color: Colors.black87,
                                  ),
                                  onPressed: () {
                                    print("List Clicked");
                                  }),
                              IconButton(
                                  icon: Icon(
                                    Icons.grid_view,
                                    color: Colors.black,
                                  ),
                                  onPressed: () {
                                    print("Grid Clicked");
                                  }),
                            ],
                          )
                        ],
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Obx(() {
              if (productController.isLoading.value)
                return Center(child: CircularProgressIndicator());
              else
                print("Total Products = " +
                    productController.productList.length.toString());
              return ListView.builder(
                itemCount: productController.productList.length,
                itemBuilder: (context, index) {
                  return Column(
                    children: [
                      Row(
                        children: [
                          Container(
                            width: 150,
                            height: 100,
                            margin: EdgeInsets.fromLTRB(16, 8, 8, 8),
                            child: ClipRRect(
                              borderRadius: BorderRadius.circular(8),
                              child: Image.network(
                                productController.productList[index].image,
                                width: 150,
                                height: 100,
                                fit: BoxFit.fill,
                                color: Colors.red,
                                colorBlendMode: BlendMode.color,
                              ),
                            ),
                          ),
                          Flexible(
                              child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                productController.,
                                style: TextStyle(fontSize: 18),
                              ),
                              Text(
                                productController.productList[index].name,
                                style: TextStyle(fontSize: 18),
                              ),
                            ],
                          ))
                        ],
                      ),
                      Container(
                        color: Colors.black12,
                        height: 2,
                      )
                    ],
                  );
                },
              );
            }),
          )
        ],
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:2)

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(),
      appBar: buildAppBar(),
      body: Column(
        children: [
          buildTextInputSearch(),
          buildProductsToolBar(),
          Obx(() => buildResultList()),
        ],
      ),
    );
  }
  /* ---------------------------------------------------------------------------- */
  Widget buildResultList() {
    GoRestService goRest = Get.find();

    return Expanded(
      child: goRest.isLoading.value!
        ? Center(child: CircularProgressIndicator())
        : ListView.builder(
          itemCount: goRest.numOfProducts,
          itemBuilder: (context, index) => Column(
            children: [

结果:

enter image description here

可以在here找到完整的代码。

答案 1 :(得分:1)

首先,您可以验证是否在此网站上正确创建了模型: https://app.quicktype.io/

如果一切正常,问题可能出在这一行:

return Product.productFromJson (jasonString);

并且在它返回的数据类型中,如果你注意到它不是一个数组,它是一个单一的对象,在这种情况下,函数应该是:

Future <Product> fetchProducts () async {...}