I am a newbie in the world of flutter and GetX package and I am trying to create a simple app using Laravel as my API service and I am sending the response from the API in JSON format and I am using Laravel resource API so it is sending some extra meta data inside the response and I have already created service model and controller in my flutter app but when I am initializing an observable variable in controller it is throwing a lot error i tried all the methods but it is working fine when i am sending only data list from the API as I have to define List<Model>.obs
in controller but the problem is happening when i am sending the proper response from API as required.
Here is my JSON response data from the API
{
"data": [
{
"id": 1,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 2,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 3,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 4,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 5,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 6,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 7,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 8,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 9,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 10,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 11,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 12,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 13,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 14,
"description": "Purchased mouse sa",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
},
{
"id": 15,
"description": "Purchased mouse",
"amount": "1200",
"type": "expense",
"user_id": 1,
"created_at": null,
"updated_at": null
}
],
"links": {
"first": "http://localhost:8000/api/transactions?page=1",
"last": "http://localhost:8000/api/transactions?page=2",
"prev": null,
"next": "http://localhost:8000/api/transactions?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 2,
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "http://localhost:8000/api/transactions?page=1",
"label": 1,
"active": true
},
{
"url": "http://localhost:8000/api/transactions?page=2",
"label": 2,
"active": false
},
{
"url": "http://localhost:8000/api/transactions?page=2",
"label": "Next »",
"active": false
}
],
"path": "http://localhost:8000/api/transactions",
"per_page": 15,
"to": 15,
"total": 16
}
}
And here is my service class
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:m_budget/models/transaction.dart';
class TransactionService {
static var client = http.Client();
static Future<Transaction> fetchTransactions() async {
var res = await client.get("http://10.0.2.2:8000/api/transactions");
if (res.statusCode == 200) {
return transactionFromJson(res.body);
} else {
return null;
}
}
}
And this is my controller
The main problem is while declaring the observable variable check line no 6 in controller
This one var transactions = Transaction().obs;
import 'package:get/get.dart';
import 'package:m_budget/models/transaction.dart';
import 'package:m_budget/services/transaction_service.dart';
class TransactionController extends GetxController {
var isLoading = true.obs;
var transactions = Transaction().obs;
@override
void onInit() {
fetchTransactions();
super.onInit();
}
void fetchTransactions() async {
isLoading(true);
try {
var txns = await TransactionService.fetchTransactions();
if (txns != null) {
isLoading(false);
transactions(txns);
}
} catch (e) {} finally {
isLoading(false);
}
}
}
And model code is this
// To parse this JSON data, do
//
// final transaction = transactionFromJson(jsonString);
import 'dart:convert';
Transaction transactionFromJson(String str) =>
Transaction.fromJson(json.decode(str));
String transactionToJson(Transaction data) => json.encode(data.toJson());
class Transaction {
Transaction({
this.data,
this.links,
this.meta,
});
List<Datum> data;
Links links;
Meta meta;
factory Transaction.fromJson(Map<String, dynamic> json) => Transaction(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
links: Links.fromJson(json["links"]),
meta: Meta.fromJson(json["meta"]),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"links": links.toJson(),
"meta": meta.toJson(),
};
}
class Datum {
Datum({
this.id,
this.description,
this.amount,
this.type,
this.userId,
this.createdAt,
this.updatedAt,
});
int id;
String description;
String amount;
String type;
int userId;
dynamic createdAt;
dynamic updatedAt;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
description: json["description"],
amount: json["amount"],
type: json["type"],
userId: json["user_id"],
createdAt: json["created_at"],
updatedAt: json["updated_at"],
);
Map<String, dynamic> toJson() => {
"id": id,
"description": description,
"amount": amount,
"type": type,
"user_id": userId,
"created_at": createdAt,
"updated_at": updatedAt,
};
}
class Links {
Links({
this.first,
this.last,
this.prev,
this.next,
});
String first;
String last;
dynamic prev;
String next;
factory Links.fromJson(Map<String, dynamic> json) => Links(
first: json["first"],
last: json["last"],
prev: json["prev"],
next: json["next"],
);
Map<String, dynamic> toJson() => {
"first": first,
"last": last,
"prev": prev,
"next": next,
};
}
class Meta {
Meta({
this.currentPage,
this.from,
this.lastPage,
this.links,
this.path,
this.perPage,
this.to,
this.total,
});
int currentPage;
int from;
int lastPage;
List<Link> links;
String path;
int perPage;
int to;
int total;
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
currentPage: json["current_page"],
from: json["from"],
lastPage: json["last_page"],
links: List<Link>.from(json["links"].map((x) => Link.fromJson(x))),
path: json["path"],
perPage: json["per_page"],
to: json["to"],
total: json["total"],
);
Map<String, dynamic> toJson() => {
"current_page": currentPage,
"from": from,
"last_page": lastPage,
"links": List<dynamic>.from(links.map((x) => x.toJson())),
"path": path,
"per_page": perPage,
"to": to,
"total": total,
};
}
class Link {
Link({
this.url,
this.label,
this.active,
});
String url;
dynamic label;
bool active;
factory Link.fromJson(Map<String, dynamic> json) => Link(
url: json["url"] == null ? null : json["url"],
label: json["label"],
active: json["active"],
);
Map<String, dynamic> toJson() => {
"url": url == null ? null : url,
"label": label,
"active": active,
};
}
Please guys help me in this I am trying from last7 days but no success.
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": [
....
}
}
''';