Giulia
Giulia

Reputation: 807

How to properly JSON encode/decode a Duration field in Flutter

I am using convert package for the following task:

factory Brick.fromJson(Map<String, dynamic> json) {
    return Brick(
      title: json['title'],
      expectedDuration: json['expected_duration'],
    );
  }


Future<Brick> createBrick(
      String title, Duration expDur) async {
    var url = 'https://api.com/bricks/';
    
    final response = await http.post(
      url,
      headers: <String, String>{
        "Content-Type": "application/json; charset=UTF-8",
      },
      body: convert.jsonEncode(<String, dynamic>{
        "title": "$title",
        "expected_duration": expDur,
      }),
    );
    if (response.statusCode == 201) {
      Brick newBrick = Brick.fromJson(convert.jsonDecode(response.body));
      notifyListeners();
      return newBrick;
    } else {
      throw Exception(
          '${response.statusCode} ${response.reasonPhrase}');
    }
  }

When I call the createBrick function, I get the following error:

Unhandled Exception: Converting object to an encodable object failed: Instance of 'Duration'

How should I convert Duration? There's no mention of it on the Duration class documentation.

Thank you.

Upvotes: 2

Views: 1649

Answers (2)

Rohit Kokate
Rohit Kokate

Reputation: 11

If you're receiving a Duration value in this form, gmt_offset: "-04:00:00", it's simpler and cleaner to use an extension to convert this into a Duration field.

extension StringExtensions on String {
  Duration toDuration() {
    if (isEmpty) throw Exception('String is empty.');
    if (split(':').length == 3) {
      List<String> periods = split(':');

      return Duration(
          hours: int.parse(periods[0]),
          minutes: int.parse(periods[1]),
          seconds: int.parse(periods[2]));
    }
    throw Exception('Invalid duration value $this');
  }
}

Upvotes: 0

fartem
fartem

Reputation: 2541

You can put into JSON seconds (or milliseconds, depends on your features) from Duration:

'expected_duration': expDur.inSeconds,

And work with expected_duration as seconds:

expectedDuration: Duration(seconds: json['excepted_duration']),

If you have a duration that less than one second (milliseconds), you should to use milliseconds instead of seconds.

Upvotes: 6

Related Questions