如何从API获取产品列表

发布于 2025-01-10 16:08:32 字数 3296 浏览 1 评论 0原文

在我的示例中,我尝试调用 API 并获取产品列表。获取单个产品并将其转换为 dart 对象已经可以了。然而,当我尝试获取产品列表时,我无法做到这一点。

我阅读了 Flutter 的官方文档,但他们只展示了如何从 API 中检索 1 个项目,而不是项目列表......

我检查了很多教程,但它似乎也不太有效。 我从没想过这会那么难。

结构

我有一个product_service负责API调用,我有一个product模型。其中包含属性(例如名称)。

代码是什么样的?

Product_service.dart

// Endpoint : Get product by id
  Future<Product> getProductById(int productId) async {
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);

    var response = await http.get(
        Uri.parse(
            'https://website/wp-json/wc/v3/products/${productId}'),
        headers: <String, String>{'authorization': basicAuth});
    if (response.statusCode == 200) {
      //return response.body;
      return Product.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to load product');
    }
// Endpoint : Get all products
  Future<List<Product>> getAllProducts() async {
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);

    Product? product;

    var r = await http.get(
        Uri.parse(
            'https://website/wp-json/wc/v3/products?post_per_page=1'),
        headers: <String, String>{'authorization': basicAuth});
    if (r.statusCode == 200) {
      print(r.body);
      product = Product().productsFromJson(jsonDecode(r.body));
    }
    return [];
  }

产品模型

class Product {
  // Properties
  String name;
  String description;
  String price;
  List<dynamic> images;
  int stockQuantity;
  List<Category> categories;
  // Constructor
  Product(
      {required this.name,
      required this.description,
      required this.price,
      required this.stockQuantity,
      required this.images,
      required this.categories});

  // Make a product object from json
  factory Product.fromJson(Map<String, dynamic> json) {
    List<Category> categorieList = [];
    for (var cat in json['categories']) {
      Category category = Category(name: cat['name'], slug: cat['slug']);
      categorieList.add(category);
    }

    return Product(
        name: json['name'],
        description: json['description'],
        price: json['price'],
        stockQuantity: json['stock_quantity'],
        images: json['images'],
        categories: categorieList);
  }

// Make list of products from json 
List<Product> productsFromJson(Map<String, dynamic> json) {
    List<Product> products = [];
    json.forEach((key, value) {
      Product p = Product.fromJson(value);
      products.add(p);
    });
    return products;
}

出了什么问题?

我保留了一些代码,以使代码对每个人都更具可读性。我尝试在我的产品模型中添加额外的功能,但无法在我的product_service.dart 中调用它。这是因为名称和价格等参数是必需的。我可以将其全部设为空并执行以下操作:

String? name;

但我不确定这是否是最佳实践。 解决这个问题的最佳实践是什么?

我还有一个关于 Future 的问题。当有人可以在没有 Future 的情况下使用 Async 和 Await 然后返回列表时,为什么还要使用 future?

谢谢大家!

I am trying to call an API and get a list of products in my example. Getting a single product and convert it into a dart object works already. However when I try to get a list of products I can't manage to do that.

I read the official documentation of Flutter but they only show how to retrieve 1 item from the API instead of a list of items...

I checked a lot of tutorials but it does not seem to work that well either. I never thought this would be that hard.

Structure

I got a product_service that is responsible for the API call and I got a product model. Which contains the properties (name for example).

How does the code look like?

product_service.dart

// Endpoint : Get product by id
  Future<Product> getProductById(int productId) async {
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);

    var response = await http.get(
        Uri.parse(
            'https://website/wp-json/wc/v3/products/${productId}'),
        headers: <String, String>{'authorization': basicAuth});
    if (response.statusCode == 200) {
      //return response.body;
      return Product.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to load product');
    }
// Endpoint : Get all products
  Future<List<Product>> getAllProducts() async {
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);

    Product? product;

    var r = await http.get(
        Uri.parse(
            'https://website/wp-json/wc/v3/products?post_per_page=1'),
        headers: <String, String>{'authorization': basicAuth});
    if (r.statusCode == 200) {
      print(r.body);
      product = Product().productsFromJson(jsonDecode(r.body));
    }
    return [];
  }

product model

class Product {
  // Properties
  String name;
  String description;
  String price;
  List<dynamic> images;
  int stockQuantity;
  List<Category> categories;
  // Constructor
  Product(
      {required this.name,
      required this.description,
      required this.price,
      required this.stockQuantity,
      required this.images,
      required this.categories});

  // Make a product object from json
  factory Product.fromJson(Map<String, dynamic> json) {
    List<Category> categorieList = [];
    for (var cat in json['categories']) {
      Category category = Category(name: cat['name'], slug: cat['slug']);
      categorieList.add(category);
    }

    return Product(
        name: json['name'],
        description: json['description'],
        price: json['price'],
        stockQuantity: json['stock_quantity'],
        images: json['images'],
        categories: categorieList);
  }

// Make list of products from json 
List<Product> productsFromJson(Map<String, dynamic> json) {
    List<Product> products = [];
    json.forEach((key, value) {
      Product p = Product.fromJson(value);
      products.add(p);
    });
    return products;
}

What goes wrong?

I kept some code out to make the code more readable for everyone. I tried to add an extra function in my product model but I cannot call it in my product_service.dart. This is because the parameters like name and price is required. I can make it all nullable and do the following:

String? name;

But I am not sure if this is a best practice to do. What is the best practice for this problem?

I also have a question about Future. Why should you use future when someone can use Async and Await without Future and then return a List?

Thank you all!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泪是无色的血 2025-01-17 16:08:32

当您像这样编辑模型类时,问题将得到解决,

class Product {
  // Properties
  String name;
  String description;
  String price;
  List<dynamic> images;
  int stockQuantity;
  List<Category> categories;
  // Constructor
  Product(
      {required this.name,
      required this.description,
      required this.price,
      required this.stockQuantity,
      required this.images,
      required this.categories});

       factory Product.fromJson(Map<String, dynamic> json) =>
      Product(
        name:json["name"],
        description:json["description"],
        price:json["price"],
        stockQuantity:json["stockQuantity"],
        images:json["images"],

        categories: List<Category>.from(
                json["categories"].map((x) => Category.fromJson(x))),
      );
}

类别模型应该是这样的:

    class Category {
  // Properties
  String categoryName;
  String categoryDescription;
  String categoryImages;
  // Constructor
  Category({
    required this.categoryName,
    required this.categoryDescription,
    required this.categoryImages,
  });
  factory Category.fromJson(Map<String, dynamic> json) => Category(
        categoryName: json["categoryName"],
        categoryDescription: json["categoryDescription"],
        categoryImages: json["categoryImages"],
      );
}

When you edit the model class like this the problem will be solved,

class Product {
  // Properties
  String name;
  String description;
  String price;
  List<dynamic> images;
  int stockQuantity;
  List<Category> categories;
  // Constructor
  Product(
      {required this.name,
      required this.description,
      required this.price,
      required this.stockQuantity,
      required this.images,
      required this.categories});

       factory Product.fromJson(Map<String, dynamic> json) =>
      Product(
        name:json["name"],
        description:json["description"],
        price:json["price"],
        stockQuantity:json["stockQuantity"],
        images:json["images"],

        categories: List<Category>.from(
                json["categories"].map((x) => Category.fromJson(x))),
      );
}

Category model should be like this:

    class Category {
  // Properties
  String categoryName;
  String categoryDescription;
  String categoryImages;
  // Constructor
  Category({
    required this.categoryName,
    required this.categoryDescription,
    required this.categoryImages,
  });
  factory Category.fromJson(Map<String, dynamic> json) => Category(
        categoryName: json["categoryName"],
        categoryDescription: json["categoryDescription"],
        categoryImages: json["categoryImages"],
      );
}
随心而道 2025-01-17 16:08:32
 Future<List<Product>> getAllProducts() async {
String basicAuth =
    'Basic ' + base64Encode(utf8.encode('$username:$password'));
print(basicAuth);

//Removed the product type 

var r = await http.get(
    Uri.parse(
        'https://website/wp-json/wc/v3/products?post_per_page=1'),
    headers: <String, String>{'authorization': basicAuth});

//Made your code a little more readable here
if (r.statusCode == 200) {
  String data = response.body;
  var decodedData  = json.decode(data);
  return decodedData;

}else {
return r.statusCode;
}

//Now to get a list of products you need a new function 

 Future<List<Product>> getProductsList () async{
 //Here we will call the data from the API into a variable 
  var products = await getAllProducts();
  List<Product> productList = [];
   
  for( p in products){
   Product _product = Product(
    name : p['name'],
    description :p['description'],

 //I trust you get the gist here, do this for all map values

   );

 //Here we are going to add each of the items to the list above

   productList.add(Product.fromjson(p));
  
  }
   return productList;
 }

您将需要使用 {Product} 类型的 FutureBuilder 来显示您的项目

 Future<List<Product>> getAllProducts() async {
String basicAuth =
    'Basic ' + base64Encode(utf8.encode('$username:$password'));
print(basicAuth);

//Removed the product type 

var r = await http.get(
    Uri.parse(
        'https://website/wp-json/wc/v3/products?post_per_page=1'),
    headers: <String, String>{'authorization': basicAuth});

//Made your code a little more readable here
if (r.statusCode == 200) {
  String data = response.body;
  var decodedData  = json.decode(data);
  return decodedData;

}else {
return r.statusCode;
}

//Now to get a list of products you need a new function 

 Future<List<Product>> getProductsList () async{
 //Here we will call the data from the API into a variable 
  var products = await getAllProducts();
  List<Product> productList = [];
   
  for( p in products){
   Product _product = Product(
    name : p['name'],
    description :p['description'],

 //I trust you get the gist here, do this for all map values

   );

 //Here we are going to add each of the items to the list above

   productList.add(Product.fromjson(p));
  
  }
   return productList;
 }

You will need to make use of a FutureBuilder of type {Product} to display your items

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文