I am using the json_serializable package in Dart to convert my objects to JSON so I can then store them in a SQLite database. I am struggling in converting one particular property on my class because it is a map, the keys of which are another object. When running build_runner, I get the following error:
Could not generate
fromJson
code forboardData
because of type
PlayerModel
. Map keys must be one of: Object, dynamic, enum, String,
BigInt, DateTime, int, Uri.
Below is my PlayerModel class (the key), which is really simple. I have already implemented / generated the toJson and fromJson methods here.
import 'package:json_annotation/json_annotation.dart';
import 'package:uuid/uuid.dart';
part 'player_model.g.dart';
const uuid = Uuid();
@JsonSerializable(explicitToJson: true)
class PlayerModel {
PlayerModel({
required this.name,
}) : id = uuid.v4();
final String id;
String name;
/// Convert to [PlayerModel] from JSON
factory PlayerModel.fromJson(Map<String, dynamic> data) =>
_$PlayerModelFromJson(data);
/// Convert to JSON from [PlayerModel]
Map<String, dynamic> toJson() => _$PlayerModelToJson(this);
/// Convert the [PlayerModel] to a string
@override
String toString() {
return 'PlayerModel{id: $id, name: $name}';
}
}
And below is an extract from my BoardModel class, which is what I am trying to write the converter classes in.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:counter/models/player_model.dart';
part 'board_model.g.dart';
const uuid = Uuid();
@JsonSerializable(explicitToJson: true)
class BoardModel {
<SNIP>
}) : id = id ?? uuid.v4();
final String id;
final String name;
final double increment;
final Map<PlayerModel, double> boardData; // Players and scores for the board
final PlayerModel owner;
final DateTime lastUpdated;
final String? prefix;
final String? suffix;
/// Create a [BoardModel] from a map
factory BoardModel.fromJson(Map<String, dynamic> data) =>
_$BoardModelFromJson(data);
/// Convert the [BoardModel] to a map
Map<String, dynamic> toJson() => _$BoardModelToJson(this);
}
}
// TODO - Convert PlayerModel to nested JSON?
class BoardDataConverter
implements JsonConverter<Map<PlayerModel, double>, String> {
const BoardDataConverter();
@override
Map<PlayerModel, double> fromJson(String json) => jsonDecode(json);
@override
String toJson(Map<PlayerModel, double> data) => jsonEncode(data);
}
The BoardDataConverter class is the work in progress. I suspect I need to somehow convert / call the toJson method on the PlayerModels in the map as part of the conversion, but I’m not sure if that’s correct or how to do that. Any help appreciated.
2
Answers
Resolved. My own silly oversight. I was not calling my converter function by annotating the property in my class. Solution was to add @BoardDataConverter() as below.
You can use this inbuilt method to convert maps to json.
Answer from https://stackoverflow.com/a/29294323/23001029