Search code examples
jsondartto-json

How to create json encodable classes in dart


This question is related to this post.

I tried the following code:

import 'dart:convert';

/*server side Post class */
class Post {
  int post_id;
  String title;
  String description;
  DateTime posted_at;
  DateTime last_edited;
  String user;
  String editor;
  int up_votes;
  int down_votes;
  int total_votes;
  String links_to;
  List<String> tags = new List();

  Post.fromSQL(List sql_post) {
     //initialization code, unrelated.
  }

  Map toJson(){
    Map fromObject = {
      'post_id' : post_id,
      'title' : title,
      'description' : description,
      'posted_at' : posted_at,
      'last_edited' : last_edited,
      'user' : user,
      'editor' : editor,
      'up_votes' : up_votes,
      'dwon_votes' : down_votes,
      'total_votes' : total_votes,
      'links_to' : links_to,
      'tags' : tags
    };

    return fromObject;
    //I use the code below as a temporary solution
    //JSON.encode(fromObject, toEncodable: (date)=>date.toString());
  }
}

I have a temporary solution, but I would really like to be able to do the following.

JSON.encode(posts, toEncodable: (date)=>date.toString())

where posts is a list of Post objects. I would expect this to convert into a json list of json representations of the Post class. What I get is a list of "Instance of 'Post'" strings. So the question is, is this syntax no longer supported, or should I do something differently?


Solution

  • It seems you can only use toEncodable: OR the toJson() fallback.

    If you wrap your Date in a class which provides toJson() you don't need to use toEncodable::

    class JsonDateTime {
      final DateTime value;
      JsonDateTime(this.value);
    
      String toJson() => value != null ? value.toIso8601String() : null;
    }
    
    class Post {
      ...
      Map toJson() => {
        'post_id' : post_id,
        'title' : title,
        'description' : description,
        'posted_at' : new JsonDateTime(posted_at),
        'last_edited' : new JsonDateTime(last_edited),
        'user' : user,
        'editor' : editor,
        'up_votes' : up_votes,
        'dwon_votes' : down_votes,
        'total_votes' : total_votes,
        'links_to' : links_to,
        'tags' : tags
      };
    }
    

    or alternatively ensure that your toEncodeable: handles every not supported type:

    print(JSON.encode(data, toEncodable: (value) {
      if (value is DateTime) {
        return value.toIso8601String();
      } else {
        return value.toJson();
      }
    }));