Search code examples
flutterrestadonis.js

How can I access data from API in different widgets in Flutter


I created API for my Flutter app.

Here I printed json decoded response.body:

{data: [{id: 7, provider_id: 1, uid: 2194250, name: , account_id: 1950002701, owner_id: 1, advisor_id: 2111785, currency: €, account_type: Investment, status: Confirmed, is_active: true, opened_at: null, created_at: 2023-11-27T14:06:59.610+01:00, updated_at: 2023-11-27T14:06:59.610+01:00}]}

Here is how I am handling data from API:

if (response.statusCode == 200) {
    var jsonResponse = json.decode(response.body);
    print(jsonResponse);
    AccountController accountController = Get.find<AccountController>();
    accountController.updateAccountData(jsonResponse);
  } else {
    Map<String, dynamic> jsonResponse = json.decode(response.body);
    print(jsonResponse);
  }

Here is my AccountController.dart file

import 'package:get/get.dart';

class AccountController extends GetxController {
  RxList<Map<String, dynamic>> accountData = <Map<String, dynamic>>[].obs;

  void updateAccountData(Map<String, dynamic> data) {
    accountData.assignAll([data]);
  }
}

I also put Get.put(AccountController()); into my main.dart file.

This is how I am calling accountController in different widget

  AccountController? accountController;
  String? currency;
  String? accountType;

  @override
  void initState() {
    super.initState();
    accountController = Get.find<AccountController>();
  }

My question is, how can I loop trough this array and render items? Maybe I did everything wrong, I am new to flutter and hope I will learn something.


Solution

  • Okay, First of all, ignore all comments that says change your state management, since you are new to flutter, it is good for you because it will simplify things.

    Now:

    Data Modeling

    instead of writing something like this:
      Map<String, dynamic> jsonResponse = json.decode(response.body);
    

    or this:

    RxList<Map<String, dynamic>> accountData = <Map<String, dynamic>>[].obs;
    

    It will be better to convert the JSON to a Datatype object, (Class).

    the easiest way to do that is to use third-party tools such as : https://app.quicktype.io/
    copy your response and paste it into the website, then select Dart as a programming language. the website will generate a class for you like this:

    // To parse this JSON data, do
    //
    //     final dataModel = dataModelFromJson(jsonString);
    
    import 'dart:convert';
    
    DataModel dataModelFromJson(String str) => 
    DataModel.fromJson(json.decode(str));
    
    String dataModelToJson(DataModel data) => json.encode(data.toJson());
    
    class DataModel {
        List<Datum>? data;
    
        DataModel({
            this.data,
        });
    
        factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
            data: json["data"] == null ? [] : 
     List<Datum>.from(json["data"]!.map((x) => Datum.fromJson(x))),
      );
    
      Map<String, dynamic> toJson() => {
        "data": data == null ? [] : List<dynamic>.from(data!.map((x) => 
       x.toJson())),
      };
    }
    
    class Datum {
        int? id;
        int? providerId;
        int? uid;
        String? name;
        int? accountId;
        int? ownerId;
        int? advisorId;
        String? currency;
        String? accountType;
        String? status;
        bool? isActive;
        dynamic openedAt;
        DateTime? createdAt;
        DateTime? updatedAt;
    
    Datum({
        this.id,
        this.providerId,
        this.uid,
        this.name,
        this.accountId,
        this.ownerId,
        this.advisorId,
        this.currency,
        this.accountType,
        this.status,
        this.isActive,
        this.openedAt,
        this.createdAt,
        this.updatedAt,
    });
    
    factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        id: json["id"],
        providerId: json["provider_id"],
        uid: json["uid"],
        name: json["name"],
        accountId: json["account_id"],
        ownerId: json["owner_id"],
        advisorId: json["advisor_id"],
        currency: json["currency"],
        accountType: json["account_type"],
        status: json["status"],
        isActive: json["is_active"],
        openedAt: json["opened_at"],
        createdAt: json["created_at"] == null ? null : 
         DateTime.parse(json["created_at"]),
        updatedAt: json["updated_at"] == null ? null : 
        DateTime.parse(json["updated_at"]),
    );
    
    Map<String, dynamic> toJson() => {
        "id": id,
        "provider_id": providerId,
        "uid": uid,
        "name": name,
        "account_id": accountId,
        "owner_id": ownerId,
        "advisor_id": advisorId,
        "currency": currency,
        "account_type": accountType,
        "status": status,
        "is_active": isActive,
        "opened_at": openedAt,
        "created_at": createdAt?.toIso8601String(),
        "updated_at": updatedAt?.toIso8601String(),
      };
    }
    

    Parsing JSON to Data Model

    if (response.statusCode == 200) {
     /// var jsonResponse = json.decode(response.body);
     final dataModel = dataModelFromJson(response.body);
     AccountController accountController = Get.find<AccountController>();
     accountController.updateAccountData(dataModel);
       } else {
        /// do some logic to show error.
      }
    

    and in your controller:

    import 'package:get/get.dart';
    
    class AccountController extends GetxController {
     DateModel? dataModel
    
    void updateAccountData(DataModel data) {
    dataModel = data;
      }
    }
    

    And Please Note: this way is not organized, but in start it's good for you to make your first API call, read more about MVC, and do not start with complex level of coding.