Тема: Хтось тут шарить у Dart/Flutter? Збереження даних у json.
Я оце почав вивчати, вже доволі давно, але схоже, я гальмо і вже не можу вивчити щось складніше за PHP. Спотикаюся на елементарних моментах постійно.
Для навчання вибрав собі задачу - створити простенький todolist. Так от коли додаєш таску воно його зберігає у файл, а коли перезапускаєш - не може перечитати, бо виявляється невірний формат (насилу вдалося з'ясувати, бо дебажить це я теж ще не навчився нормально).
Короче код. Є такий клас:
class Task extends Object {
final int id;
String title;
Task(this.id, this.title);
Task.fromJson(Map<String, dynamic> json)
: id = json['id'] as int,
title = json['title'] as String;
Map<String, dynamic> toJson() => {
'id': id,
'title': title
};
}
Як це робити я підгледів отут:
https://docs.flutter.dev/data-and-backend/serialization/json#manual-encoding
Ось, клас, що відповідає за збереження даних:
import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
import 'package:todolist/task.dart';
class TodoStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
final file = File('$path/todolist/todo.txt');
if (!(await file.exists())) {
file.create(recursive: true);
}
return file;
}
Future<List<Task>> getTodo() async {
List<Task> tasks = [];
try {
final file = await _localFile;
final contents = await file.readAsString();
LineSplitter ls = const LineSplitter();
List<String> jsons = ls.convert(contents);
tasks = jsons.map((el) {
var taskMap = jsonDecode(el);
return Task.fromJson(taskMap);
}).toList();
} catch (e) {
// @TODO: show error message
print(e);
}
return tasks;
}
Future<File> putTodo(List<Task> todo) async {
final file = await _localFile;
List<String> jsons = todo.map((el) {
return el.toJson().toString();
}).toList();
try {
file.writeAsString(jsons.join('\n'));
} catch (e) {
// @TODO: show error message
return file;
}
return file;
}
}
По суті, воно працює, але проблема в тому, що оте putTodo() зберігає якийсь неправильний json без лапок. Коли я пофіксив файл вручну, додавши лапки, воно запрацювало, тобто getTodo() повернуло дані без виключення.
Як його змусити зберігати json з лапками?
Ось приклад, як воно зберігає:
{id: 1713375875, title: Test01}
{id: 1713375893, title: Happiness!!!}
{id: 1713526370, title: Next}
А ось, як мало би бути, щоб потім могло прочитати:
{"id": 1713375875, "title": "Test01"}
{"id": 1713375893, "title": "Happiness!!!"}
{"id": 1713526370, "title": "Next"}