flutter different ways of displaying api data on to build widgets (Get X)

hur-kyuh-leez·2022년 5월 7일
0

서문

기초 입문서에서 보통은 아래와 같이 알려준다.
Do it 플러터 예제
위와 같이 한 파일에서 스테이트 관리 하는 것은 쉽지만,
MVC 패턴 같은 디자인 패턴을 활용하여 코드를 정리 하려고 하면,
스테이트 관리 하는 것도 따로 해줘야 한다.

모든 프레임워크에서 스테이트가 나오는 순간 더 어려워 진다.
플러터는 특히 더 어렵게 느껴진다.
왜냐하면 다트가 typed 언어라서 스테이트 관리하는 obj도 알아야 하기 때문이다.

또한,
flutter console 창에 데이터를 띄었다고 해서 앱화면에 동일한 코드를 써서 띄우려고 하면 안되는 경우가 많다. 그래서 flutter는 ui 디자인 할 때는 쉽지만 data 연결 할 때는 난의도가 급격하게 올라간다.

json Data

예제 들어가기 앞써,
아래와 같은 json data가 넘어 온다고 가정 하겠다.
보통 php backend api는 아래와 같다.

// https://localhost:8000/api/fruit/{id?}

[
    {
        "id": 1,
        "name": "Banana",
        "stock": 10
    }
]

GetX 예제

가장 많이 쓰는 GetX를 사용하여 json 형태의 api data를 build widget에 그려보자.

  1. json -> obj
    가장 먼저 해야 할 것은 json으로 넘어 온 데이터를 obj화 해야 하기 때문에 model obj를 만들어 줘야 한다. boiler plate 이나 oop를 한번 쯤 배웠다면 self explanatory 한 코드 이다. (factory에 관해서는 한번 찾아 보기를 권한다.)

model

// lib/model/fruit.dart

class Fruit{
  final int id;
  final String name;
  final int stock;

  LaravelApiModel({
    required this.id,
    required this.name,
    required this.stock,
  });
  
  
// json to Map obj
  factory Fruit.fromJson(Map<String, dynamic> json) =>
      Fruit(
        id: json['id'],
        name: json['name'],
        stock: json['stock'],
      );
      
// Map obj to json
  Map<String, dynamic> toJson() =>
      {
        'id': id,
        'name': name,
        'stock': stock,
      };
}
  1. 모델이 준비가 되었다면 이제 api 요청을 하면서 GetX로 state 관리를 해보자

controller

// lib/controller/api_controller.dart

import 'dart:convert';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../model/fruit.dart';

class ApiController extends GetxController{
 // indicating this controller is using GetX
 static ApiController instance = Get.find();
  
  // defining GetX variable using keyword Rx
  late Rx<Fruit> _fruit;
  
  // setting getter
  Fruit get fruit =>  _fruit.value;


  void fetch(int id) async {
    final response = await http
        .get(Uri.parse('http://127.0.0.1:8000/api/furit/$id'));

    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      var json = await jsonDecode(response.body)[0];
      Fruit whichFruit = Fruit.fromJson(json);
      fruit.value = whichFruit;

    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception('Failed to load');
    }
  }
}

GetX를 활용하기 위해, lib/main.dart에서
MaterialApp()
GetMaterialApp()으로 바꾸는 걸 잊지 말자.

  1. 모델과 api 요청과 state 관리 준비가 되었으니 한번 display를 해보자

View

// screen/screen.dart

class Screen extends StatelessWidget {
  var controller = Get.put(ApiController());
  var apiController = ApiController.instance;
  
  @override
  Widget build(BuildContext context) {
    apiController.fetch(1);
    return Column(
      children: [
        Row(
          children: [
          // 
            Text(apiController.Fruit.name),
          ],
        ),
      ],
    );
  }
}

이외 FutureBuilder를 사용하여 할 수 도 있다.
이건 flutter official doc에 있는 cookbook에 설명이 잘 되어 있으니 참조 바란다. 검색을 "FutureBuilder" 라고 하면 된다.

profile
벨로그에 생각을 임시로 저장합니다. 틀린건 틀렸다고 해주세요 :) 그래야 논리 학습이 강화됩니다.

0개의 댓글