如何设置工厂专辑以映射自定义REST API JSON BODON

问题描述 投票:0回答:1
,但是我迷失了自定义专辑以匹配REST API JSON数据。特别是,正确设置专辑以容纳一系列对象(项目)和元对象。代码示例优先。预先感谢!

示例JSON数据来自RESTAPI

{ "projects": [ { "id": "7c635c45-ebab-44fc-8141-2157e062f97d", "name": "Project 1", "description": "Project description", "notice_to_proceed_date": "2024-01-01", "business_id": 4046, "status": "construction", "awarded_amount": "799109.2", "authorized_amount": "799109.2", "business_name": "My Business Name" }, { "id": "8528ebbb-54db-40e2-ba0d-1a90e3dfdfb7", "name": "Project 2", "description": "Project description", "notice_to_proceed_date": "2024-03-03", "business_id": 4046, "status": "construction", "awarded_amount": "31166.03", "authorized_amount": "31166.03", "business_name": "My Business Name" } ], "meta": { "current_page": 1, "next_page": null, "prev_page": null, "total_pages": 1, "total_count": 2 } }

我的代码

import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; Future<Album> fetchAlbum() async { final response = await http.get( Uri.parse('https://api.demo.platform.infotechinc.com/appia/v3/projects'), // Send authorization headers to the backend headers: { HttpHeaders.authorizationHeader: 'Bearer 7bec66...' }, ); if (response.statusCode == 200) { // If the server did return a 200 OK response, // then parse the JSON. return Album.fromJson(jsonDecode(response.body) as Map<String, dynamic>); } else { // If the server did not return a 200 OK response, // then throw an exception. throw Exception('Failed to load album'); } } class Album { final String id; final String name; final String description; final String notice_to_proceed_date; final int business_id; final String status; final String awarded_amount; final String authorized_amount; final String business_name; const Album({ required this.id, required this.name, required this.description, required this.notice_to_proceed_date, required this.business_id, required this.status, required this.awarded_amount, required this.authorized_amount, required this.business_name, }); factory Album.fromJson(Map<String, dynamic> json) { return switch (json) { { 'id': String id, 'name': String name, 'description': String description, 'notice_to_proceed_date': String notice_to_proceed_date, 'business_id': int business_id, 'status': String status, 'awarded_amount': String awarded_amount, 'authorized_amount': String authorized_amount, 'business_name': String business_name, } => Album( id: id, name: name, description: description, notice_to_proceed_date: notice_to_proceed_date, business_id: business_id, status: status, awarded_amount: awarded_amount, authorized_amount: authorized_amount, business_name: business_name, ), _=> throw const FormatException('Failed to load album.'), }; } } void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late Future<Album> futureAlbum; @override void initState() { super.initState(); futureAlbum = fetchAlbum(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Fetch Data Example', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), ), home: Scaffold( appBar: AppBar( title: const Text('Fetch Data Example'), ), body: Center( child: FutureBuilder<Album>( future: futureAlbum, builder: (context, snapshot) { if (snapshot.hasData) { return Text(snapshot.data!.name); } else if (snapshot.hasError) { return Text('${snapshot.error}'); } // By default, show a loading spinner. return const CircularProgressIndicator(); }, ), ), ), ); } }
link link to api文档
https://infotechinc.stoplight.io/docs/appia/df3aded65f065-list-all-projects

这里是更新的代码。

预期响应enter image description here

{ "projects": [ { "id": "7c635c45-ebab-44fc-8141-2157e062f97d", "name": "Project 1", "description": "Project description", "notice_to_proceed_date": "2024-01-01", "business_id": 4046, "status": "construction", "awarded_amount": "799109.2", "authorized_amount": "799109.2", "business_name": "My Business Name" }, { "id": "8528ebbb-54db-40e2-ba0d-1a90e3dfdfb7", "name": "Project 2", "description": "Project description", "notice_to_proceed_date": "2024-03-03", "business_id": 4046, "status": "construction", "awarded_amount": "31166.03", "authorized_amount": "31166.03", "business_name": "My Business Name" } ], "meta": { "current_page": 1, "next_page": null, "prev_page": null, "total_pages": 1, "total_count": 2 } }
json flutter dart rest
1个回答
0
投票

模型 它被重命名以匹配预期数据

class Project { final String? id; final String? name; final String? description; final DateTime? noticeToProceedDate; final int? businessId; final String? status; final String? awardedAmount; final String? authorizedAmount; final String? businessName; Project({ this.id, this.name, this.description, this.noticeToProceedDate, this.businessId, this.status, this.awardedAmount, this.authorizedAmount, this.businessName, }); Project copyWith({ String? id, String? name, String? description, DateTime? noticeToProceedDate, int? businessId, String? status, String? awardedAmount, String? authorizedAmount, String? businessName, }) => Project( id: id ?? this.id, name: name ?? this.name, description: description ?? this.description, noticeToProceedDate: noticeToProceedDate ?? this.noticeToProceedDate, businessId: businessId ?? this.businessId, status: status ?? this.status, awardedAmount: awardedAmount ?? this.awardedAmount, authorizedAmount: authorizedAmount ?? this.authorizedAmount, businessName: businessName ?? this.businessName, ); factory Project.fromJson(Map<String, dynamic> json) => Project( id: json["id"], name: json["name"], description: json["description"], noticeToProceedDate: json["notice_to_proceed_date"] == null ? null : DateTime.parse(json["notice_to_proceed_date"]), businessId: json["business_id"], status: json["status"], awardedAmount: json["awarded_amount"], authorizedAmount: json["authorized_amount"], businessName: json["business_name"], ); Map<String, dynamic> toJson() => { "id": id, "name": name, "description": description, "notice_to_proceed_date": "${noticeToProceedDate!.year.toString().padLeft(4, '0')}-${noticeToProceedDate!.month.toString().padLeft(2, '0')}-${noticeToProceedDate!.day.toString().padLeft(2, '0')}", "business_id": businessId, "status": status, "awarded_amount": awardedAmount, "authorized_amount": authorizedAmount, "business_name": businessName, }; }

api呼叫
API呼叫的重命名还指出,项目密钥是一个列表,我们获取每个项目并将其映射到我们的项目模型

Future<List<Project>?> fetchProjects() async { final response = await http.get( Uri.parse('https://api.demo.platform.infotechinc.com/appia/v3/projects'), // Send authorization headers to the backend headers: {HttpHeaders.authorizationHeader: 'Bearer 7bec66...'}, ); if (response.statusCode == 200) { // If the server did return a 200 OK response, // then parse the JSON. return List<Project>.from( ((jsonDecode(response.body)?['projects'] as List?) ?? []) .map((e) => Project.fromJson(e))); } else { // If the server did not return a 200 OK response, // then throw an exception. throw Exception('Failed to load album'); } }

main.dart

void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late Future<List<Project>?> futureAlbum; @override void initState() { super.initState(); futureAlbum = fetchProjects(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Fetch Data Example', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), ), home: Scaffold( appBar: AppBar( title: const Text('Fetch Data Example'), ), body: Center( child: FutureBuilder<List<Project>?>( future: futureAlbum, builder: (context, snapshot) { if (snapshot.hasData) { return Expanded( child: ListView.builder( itemBuilder: (_, i) { final name = snapshot.data?[i].name; return Text(name ?? ""); }, itemCount: snapshot.data?.length, shrinkWrap: true, ), ); } else if (snapshot.hasError) { return Text('${snapshot.error}'); } // By default, show a loading spinner. return const CircularProgressIndicator(); }, ), ), ), ); } }

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.