아래 코드는 factory 생성자를 일일이 타이핑을 해야 하는 번거로움이 있다.
import 'package:rest/restaurant/component/restaurant_card.dart';
import '../../common/const/data.dart';
enum RestaurantPriceRange {
expensive,
medium,
cheap,
}
class RestaurantModel {
final String id;
final String name;
final String thumbUrl;
final List<String> tags;
final RestaurantPriceRange priceRange;
final double ratings;
final int ratingsCount;
final int deliveryTime;
final int deliveryFee;
RestaurantModel({
required this.id,
required this.name,
required this.thumbUrl,
required this.tags,
required this.priceRange,
required this.ratings,
required this.ratingsCount,
required this.deliveryTime,
required this.deliveryFee,
});
factory RestaurantModel.fromJson({
required Map<String, dynamic> json,
}) {
return RestaurantModel(
id: json['id'],
name: json['name'],
thumbUrl: 'http://$realIp${json['thumbUrl']}',
tags: List<String>.from(json['tags']),
priceRange: RestaurantPriceRange.values.firstWhere(
(e) => e.name == json['priceRange'],
),
ratings: json['ratings'],
ratingsCount: json['ratingsCount'],
deliveryTime: json['deliveryTime'],
deliveryFee: json['deliveryFee'],
);
}
}
|
위 코드에서 factory 생성자 코드 부분을 자동 생성하는 방법으로 JSON Serialize 를 이용한다.
1. https://pub.dev/packages/json_serializable 에서 최신버전을 확인한다.
Readme 탭에서 Setup 부분의 example 을 누르면 pubspec.yaml 에 추가할 버전이 나온다.
아래의 라이브러리를 추가하고 flutter pub get 명령을 실행한다.
dependencies:
json_annotation: ^4.8.0
dev_dependencies:
build_runner: ^2.3.3
json_serializable: ^6.7.1
|
Class 위에 @JsonSerializable() 을 추가하고, part 'restaurant_model.g.dart'; 코드를 추가한다.
그리고 나서 터미널 창을 열면 프로젝트 root 폴더가 된다.
root에서 dart run build_runner build 를 입력하고 실행한다.
매번 입력하기 귀찮다면 dart run build_runner watch 명령어를 실행하면 된다.
import 'package:json_annotation/json_annotation.dart';
import 'package:rest/common/utils/data_utils.dart';
part 'restaurant_model.g.dart';
/**
* 수정 사항이 생기면 터미널에서 dart run build_runner build 를 다시 실행한다.
* 그러면 자동으로 g.dart 파일을 업데이트한다.
*/
enum RestaurantPriceRange {
expensive,
medium,
cheap,
}
@JsonSerializable()
class RestaurantModel {
final String id;
final String name;
@JsonKey(
fromJson: DataUtils.pathToUrl,
)
final String thumbUrl;
final List<String> tags;
final RestaurantPriceRange priceRange;
final double ratings;
final int ratingsCount;
final int deliveryTime;
final int deliveryFee;
RestaurantModel({
required this.id,
required this.name,
required this.thumbUrl,
required this.tags,
required this.priceRange,
required this.ratings,
required this.ratingsCount,
required this.deliveryTime,
required this.deliveryFee,
});
factory RestaurantModel.fromJson(Map<String, dynamic> json)
=> _$RestaurantModelFromJson(json);
Map<String, dynamic> toJson() => _$RestaurantModelToJson(this);
// factory RestaurantModel.fromJson({
// required Map<String, dynamic> json,
// }) {
// return RestaurantModel(
// id: json['id'],
// name: json['name'],
// thumbUrl: 'http://$realIp${json['thumbUrl']}',
// tags: List<String>.from(json['tags']),
// priceRange: RestaurantPriceRange.values.firstWhere(
// (e) => e.name == json['priceRange'],
// ),
// ratings: json['ratings'],
// ratingsCount: json['ratingsCount'],
// deliveryTime: json['deliveryTime'],
// deliveryFee: json['deliveryFee'],
// );
// }
}
|
모델 클래스 내부에 fromJson과 toJson을 정의해 두면 해당 메서드를 호출할 때마다 오타를 걱정할 필요가 없어진다.
칼럼에서 별도 변경이 필요하면
@JsonKey(
fromJson: DataUtils.pathToUrl,
)
와 같이 추가하고 나서 dart run build_runner build 를 다시 실행한다.
그러면 restaurant_model.g.dart 파일이 업데이트되어 자동 생성된다.
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'restaurant_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RestaurantModel _$RestaurantModelFromJson(Map<String, dynamic> json) =>
RestaurantModel(
id: json['id'] as String,
name: json['name'] as String,
thumbUrl: DataUtils.pathToUrl(json['thumbUrl'] as String),
tags: (json['tags'] as List<dynamic>).map((e) => e as String).toList(),
priceRange:
$enumDecode(_$RestaurantPriceRangeEnumMap, json['priceRange']),
ratings: (json['ratings'] as num).toDouble(),
ratingsCount: json['ratingsCount'] as int,
deliveryTime: json['deliveryTime'] as int,
deliveryFee: json['deliveryFee'] as int,
);
Map<String, dynamic> _$RestaurantModelToJson(RestaurantModel instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'thumbUrl': instance.thumbUrl,
'tags': instance.tags,
'priceRange': _$RestaurantPriceRangeEnumMap[instance.priceRange]!,
'ratings': instance.ratings,
'ratingsCount': instance.ratingsCount,
'deliveryTime': instance.deliveryTime,
'deliveryFee': instance.deliveryFee,
};
const _$RestaurantPriceRangeEnumMap = {
RestaurantPriceRange.expensive: 'expensive',
RestaurantPriceRange.medium: 'medium',
RestaurantPriceRange.cheap: 'cheap',
};
|
'Flutter 앱 > Flutter Basic' 카테고리의 다른 글
Flutter Person freezed 자동완성 예제 (0) | 2023.12.09 |
---|---|
Flutter Go_Router 버전업에 따른 수정사항 (0) | 2023.12.04 |
플러터 미세먼지 공공데이터 API 신청 및 postman 에서 확인 (0) | 2023.11.08 |
Flutter Drift 로 SQLite DB 생성 및 g.dart 자동생성 (0) | 2023.11.05 |
Flutter shared_preferences 개념 정리 (0) | 2022.07.26 |