How to handle complex API data response in Flutter GetX using observable method
item_model.dart
class ItemModel { int id; String description; String amount; String type; int userId; DateTime createdAt; DateTime updatedAt; ItemModel.fromJson(Map<String, dynamic> data) { id = data['id']; description = data['description']; amount = data['amount']; type = data['type']; userId = data['userId']; if (data['created_at'] != null) createdAt = DateTime.parse(data['created_at']); if (data['updated_at'] != null) updatedAt = DateTime.parse(data['updated_at']); }}
page_links_model.dart
class PageLinksModel { String first, last, prev, next; PageLinksModel.fromJson(Map<String, dynamic> data) { first = data['first']; last = data['last']; prev = data['prev']; next = data['next']; }}
pages_status_model.dart
class PagesStatusModel { int currentPage, from, lastPage; var links = List<PageInfoModel>(); String path; int perPage, to, total; PagesStatusModel.fromJson(Map<String, dynamic> data) { currentPage = data['current_page']; from = data['from']; lastPage = data['last_page']; (data['links'] as List).forEach((e) => links.add(PageInfoModel.fromJson(e))); path = data['path']; perPage = data['per_page']; to = data['to']; total = data['total']; }}class PageInfoModel { String url; dynamic label; bool active; PageInfoModel.fromJson(Map<String, dynamic> data) { url = data['url']; label = data['label']; active = data['active']; }}
transaction_model.dart
import 'package:getx_api/models/pages_status_model.dart';class TransactionModel { var data = List<ItemModel>(); PageLinksModel links; PagesStatusModel meta; TransactionModel.fromJson(Map<String, dynamic> source) { (source['data'] as List).forEach((e) => data.add(ItemModel.fromJson(e))); links = PageLinksModel.fromJson(source['links']); meta = PagesStatusModel.fromJson(source['meta']); }}
net_service.dart
import 'dart:convert';import 'package:getx_api/src/shared/transactions_data.dart';import 'package:http/http.dart' as http;class NetService { static Future fetchJsonData(String url) { return http.get(url) .then((response) => response?.statusCode == 200 ? jsonDecode(response.body) : null) .catchError((err) => print(err)); } static Future fetchLocalJsonData() async { await Future.delayed(Duration(seconds: 3)); return jsonDecode(transactionData) as Map<String, dynamic>; }}
transaction_controller.dart
import 'package:get/get.dart';import 'package:getx_api/models/transaction_model.dart';import 'package:getx_api/services/net_service.dart';const _serverUrl = 'http://10.0.2.2:8000/api/transactions';class TransactionController extends GetxController { var _trx; var _dataAvailable = false.obs; @override void onInit() { super.onInit(); fetchTransactions(); } bool get dataAvailable => _dataAvailable.value; TransactionModel get trx => _trx; Future<void> fetchTransactions() { // return NetService.fetchJsonData(_serverUrl) return NetService.fetchLocalJsonData() .then((response) { if (response != null) _trx = TransactionModel.fromJson(response); }) .catchError((err) => print('Error!!!!! : $err')) .whenComplete(() => _dataAvailable.value = _trx != null); }}
home_page.dart
import 'package:flutter/material.dart';import 'package:get/get.dart';import 'package:getx_api/src/controllers/transaction_controller.dart';class HomePage extends StatelessWidget { /* ---------------------------------------------------------------------------- */ const HomePage({Key key}) : super(key: key); /* ---------------------------------------------------------------------------- */ @override Widget build(BuildContext context) { final obj = Get.put(TransactionController()); return Scaffold( appBar: buildAppBar(), body: Obx(() => obj.dataAvailable ? Text(obj.trx.toString()) : Text('... waiting ...')), ); } /* ---------------------------------------------------------------------------- */ AppBar buildAppBar() { return AppBar( title: Text('Hi!'), centerTitle: true, ); }}
transactions_data.dart
const transactionData = '''{ "data": [ .... }}''';