skip to Main Content

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 for boardData 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


  1. Chosen as BEST ANSWER

    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.

    @BoardDataConverter()
    final Map<PlayerModel, double> boardData; // Players and scores for the board
    

  2. import 'dart:convert';
    
    json.encode(data);
    

    You can use this inbuilt method to convert maps to json.

    Answer from https://stackoverflow.com/a/29294323/23001029

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search