Тема: Хтось тут шарить у 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"}