일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- swagger-typescript-api
- REST API
- KakaoMap
- Three-fiber
- Game js
- Excel
- webrtc
- typescript
- uint16array
- methodChannel
- uint8array
- Raycasting
- FirebaseAnalytics
- userevent_tracker
- react
- androidId
- node
- Redux
- code editor
- web track
- babel
- Flutter
- Babel standalone
- jszip
- RouteObserver
- Image Resize typescript
- identifierForVender
- Prism.js
- Completer
- Three js
- Today
- Total
Never give up
Flutter - Json serialize 본문
구글 공식문서에 따르면 다음과 같은식으로 구현을 하는데
{
"name": "John Smith",
"email": "john@example.com"
}
//변환 할 json값
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() =>
{
'name': name,
'email': email,
};
}
여기서 조금 더 생각해야되는 부분이 있습니다
예제에 나온 serialize는 불러온 json 데이터가 하나일때는 처리할때는 이렇게 하지만
여러개일때는 어떻게 해야될지 고민이 됩니다
이전 예제처럼 처리하면 간단한데 (링크 참조 : devmemory.tistory.com/10)
해당 예제에서 사용했던 방식은 network에서 jsonData를 decoding해서
바로 List로 값을 옮기기 때문에 작동은 잘 되지만
값을 불러올때 key값이 혼동될수도 있고 소규모 프로젝트에는 적합하지만
대형 프로젝트에서는 적합하지 않다고 합니다
그래서 위에 구글에서 설명한 방식으로 여러 데이터가 있는 Json을 사용하면
Map이나 List형태를 마주치게될 수 있는데 여기에서는 List부분에 대해 다루겠습니다
Data
const String commentName = 'name';
const String commentEmail = 'email';
const String commentMessage = 'body';
class CommentData {
final String name, email, message;
CommentData({this.name, this.email, this.message});
factory CommentData.fromJson(Map<String, dynamic> json) {
return CommentData(
name: json[commentName],
email: json[commentEmail],
message: json[commentMessage]);
}
}
Network
class DataNetWork {
final String url = 'https://jsonplaceholder.typicode.com/comments';
Future getData() async {
http.Response response = await http.get(url);
if (response.statusCode == 200) {
return response.body;
} else {
print(response.statusCode);
}
}
List<CommentData> getCommentData(String response) {
var data = jsonDecode(response).cast<Map<String, dynamic>>();
return data
.map<CommentData>((decodedData) => CommentData.fromJson(decodedData))
.toList();
}
}
Item
class CommentItem extends ChangeNotifier {
List<CommentData> _list = [];
UnmodifiableListView<CommentData> get getList => UnmodifiableListView(_list);
int get getLength => _list.length;
Future<void> setListData() async {
DataNetWork netWork = DataNetWork();
_list = netWork.getCommentData(await netWork.getData());
}
}
Main
class CommentExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green,
appBar: AppBar(
title: Text('Comments'),
backgroundColor: Color(0x00000000),
elevation: 0,
),
body: SafeArea(
child: Container(
padding: EdgeInsets.all(8),
child: Consumer<CommentItem>(
builder: (context, items, child) {
return ListView.builder(
itemCount: items.getLength,
itemBuilder: (context, index) {
var item = items.getList[index];
return Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Card(
elevation: 8,
color: Colors.white,
child: ListTile(
leading: CircleAvatar(
child: FlatButton(
child: Text(item.name[0],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white, fontSize: 18)),
onPressed: () =>
Container(child: Text(item.name)),
),
),
title: Text(item.email),
subtitle: Text(item.message),
)),
);
});
},
))),
);
}
}
먼저 typo를 줄이기 위해 상수로 key값을 정의 해주고
data 클래스를 구글의 예제와 같은 폼으로 만들어줍니다
network 클래스에서 네트워크에서 값을 가져오는 부분은
비동기처리를 위해 future를 사용해주고 데이터를 가져올 때
decoding된 값을 cast<Map<>>처리를 해서 castList타입을 만들어줍니다
그리고 각각 List값들을 data class에 정의해놨던 fromJson을 통해
List<원하는 데이터 타입>형태로 만들어줍니다
그 후 원하는 대로 출력 하는식으로 했는데
구글 예제에 보면 이 부분은 백그라운드에서 처리하는 방법으로
compute(List<data>, json.body)를 사용합니다
(링크 : flutter-ko.dev/docs/cookbook/networking/background-parsing)
상황에 맞게 필요한 방법을 사용하면 될거 같습니다
ps. 스플래시 화면 혹은 해당 화면으로 넘어가기 전에 setListData를 콜 해줘야됩니다
여기까지는 구글 공식문서에 대한 설명을 토대로 만들어본 예제고
더 직관적인 코드로 해보자면 먼저 json값의 형태를 파악해야됩니다
그래서 decoded json값을 출력해보면 다음과 같이 나옵니다
I/flutter (20576): [{postId: 1, id: 1, name: id labore ex et quam laborum, email: Eliseo@gardner.biz, body: laudantium enim quasi est quidem magnam voluptate ipsam eos
I/flutter (20576): tempora quo necessitatibus
I/flutter (20576): dolor quam autem quasi
I/flutter (20576): reiciendis et nam sapiente accusantium}, {postId: 1, id: 2, name: quo vero reiciendis velit similique earum, email: Jayne_Kuhic@sydney.com, body: est natus enim nihil est dolore omnis voluptatem numquam
I/flutter (20576): et omnis occaecati quod ullam at
I/flutter (20576): voluptatem error expedita pariatur
I/flutter (20576): nihil sint nostrum voluptatem reiciendis et}, {postId: 1, id: 3, name: odio adipisci rerum aut animi, email: Nikita@garfield.biz, body: quia molestiae reprehenderit quasi aspernatur
I/flutter (20576): aut expedita occaecati aliquam eveniet laudantium
I/flutter (20576): omnis quibusdam delectus saepe quia accusamus maiores nam est
I/flutter (20576): cum et ducimus et vero voluptates excepturi deleniti ratione}, {postId: 1, id: 4, name: alias odio sit, email: Lew@alysha.tv, body: non et atque
I/flutter (20576): occaecati deserunt quas accusantium unde odit nobis qui voluptatem
I/flutter (20576): quia voluptas consequuntur itaque dolor
I/flutter (20576): et qui
[{key : value}]로 List<Map<String, dynamic>> 형태가 출력되는것을 확인할 수 있습니다
List<CommentData> getCommentData(String response) {
List data = jsonDecode(response);
List<CommentData> list = [];
data.forEach((element) {
list.add(CommentData.fromJson(element));
});
return list;
}
그러면 response값을 List에 저장하고 반복문 안에서 list에 fromJson을 이용해서 add를 해줍니다
이렇게 처리해보니 조금 더 코드가 직관적으로 보이는거 같아서 필자는 후자를 선호합니다
'Flutter' 카테고리의 다른 글
Flutter - Map<key, List<data>> with Listview(simple chatting screen) (0) | 2020.11.02 |
---|---|
Flutter - Search item in List and how to keep TextField from keyboard (0) | 2020.10.05 |
Flutter - how to get item index in Listview (0) | 2020.09.30 |
Flutter - Webview with searchBar (0) | 2020.09.25 |
Flutter - how to use Icon Picker(save, load) (0) | 2020.09.18 |