flutter 모델 생성에 관하여

신석진( Seokjin Shin)·2022년 11월 11일

개요

정말 귀찮다.
json_serializableJSON to Dart 페이지를 이용하도록하자.

데이터 형식

아래와 같은 형식의 데이터를 가정하자.

{
    "page": 1,
    "data": [
        {
            "a": 1
        },
        {
            "b": 1
        }
    ]
}

JSON to Dart

페이지 사용 예시

전체 모델

반복되는 부분이 굉장히 많은 것을 볼 수 있다. Map의 key값이 클래스의 프로퍼티와 같아서 받아야할 데이터의 양의 두배를 단순 코드 기입에 사용해야한다.때문에 fromJson이랑 toJson부분은 json_serializable한테 맡기도록하자

class Test {
  int? page;
  List<Data>? data;

  Test({this.page, this.data});

  Test.fromJson(Map<String, dynamic> json) {
    page = json['page'];
    if (json['data'] != null) {
      data = <Data>[];
      json['data'].forEach((v) {
        data!.add(new Data.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['page'] = this.page;
    if (this.data != null) {
      data['data'] = this.data!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Data {
  int? a;
  int? b;

  Data({this.a, this.b});

  Data.fromJson(Map<String, dynamic> json) {
    a = json['a'];
    b = json['b'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['a'] = this.a;
    data['b'] = this.b;
    return data;
  }
}

json_serializable

모델 선언

flutter pub run build_runner watch를 실행한 뒤에
아래와 같이 파일을 저장하면 파일이름.g.dart가 생성된다.
예시의 경우 test.dart라는 이름의 파일로 진행하였다. JSON to dart에서 프로퍼티와 생성자 부분만 복사해오자.

import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';

(explicitToJson: true)
class Test {
  int? page;
  List<Data>? data;

  Test({this.page, this.data});
}

(explicitToJson: true)
class Data {
  int? a;
  int? b;

  Data({this.a, this.b});
}

JSON 관련 함수 선언

위의 예시와 같이 모델이 겹쳐 있는 경우 하위 모델의 fromJson, toJson이 선언되어야한다. 그렇지 않으면 생성된 .g.dart 파일에 오류가 발생한다.

전체 json_serializable 예시

반복되는 부분이 현저히 줄어들었음을 확인할 수 있다.

import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';

(explicitToJson: true)
class Test {
  int? page;
  List<Data>? data;

  Test({this.page, this.data});

  factory Test.fromJson(Map<String, dynamic> json) => _$TestFromJson(json);
  Map<String, dynamic> toJson() => _$TestToJson(this);
}

(explicitToJson: true)
class Data {
  int? a;
  int? b;

  Data({this.a, this.b});

  factory Data.fromJson(Map<String, dynamic> json) => _$DataFromJson(json);
  Map<String, dynamic> toJson() => _$DataToJson(this);
}

0개의 댓글