goxiaoy / flutter_survey_js

Flutter client library for parsing and display surveyjs.io survey
https://goxiaoy.github.io/flutter_survey_js/
MIT License
15 stars 15 forks source link

Date values should be `jsonEncode`-able #92

Closed laogao closed 1 year ago

laogao commented 1 year ago

Describe the bug When submitting a survey with dates, the answer is currently not jsonEncode-able. Instead, the following error will be thrown:

errors.dart:288 Uncaught (in promise) Error: Converting object to an encodable object failed: Instance of 'DateTime'

To Reproduce SurveyJs json

{
    "title": "datetime jsonEncode issue",
    "logoPosition": "right",
    "pages": [
        {
            "name": "page1",
            "elements": [
                {
                    "type": "text",
                    "name": "102 visit date",
                    "title": "Visit Date",
                    "isRequired": true,
                    "inputType": "date"
                }
            ]
        }
    ],
    "showQuestionNumbers": "off"
}

SurveyJs answer

{"102 visit date": 2023-06-07 00:00:00.000}

Expected behavior The answer is properly encoded in JSON:

  onSubmit: (v) async {
    print(jsonEncode(v));
  },

Here's how surveyjs.io handles the same input:

{"102 visit date": "2023-06-07"}

Screenshots

Desktop (please complete the following information):

laogao commented 1 year ago

This issue can be circumvented by supplying a custom encoder to jsonEncode:

  jsonEncode(v, toEncodable: (nonEncodable) => encodeDateTime(nonEncodable));

where encodeDateTime is defined as:

  dynamic encodeDateTime(dynamic item) {
    if (item is DateTime) {
      return item.toIso8601String();
    }
    return item;
  }

This would give us something like:

{"102 visit date":"2023-06-07T00:00:00.000"}

Ideally, we could do better at library level by storing the value in String in the first place (as surveyjs.io apparently does) and according to its inputType (in this particular case, a date without the time part).

goxiaoy commented 1 year ago

It's a very common dart issue. Should keep it as DateTime for further calculation like expression

laogao commented 1 year ago

It's a very common dart issue. Should keep it as DateTime for further calculation like expression

I understand the thinking behind this. That said, since DateTimes and Strings are inter-convertible, I see three reasons why we might prefer an underlying string representation (and accept the inconvenience / overhead of converting the values back and forth for calculation):

  1. This is how the official surveyjs.io treats date inputs for text fields.
  2. One would have a hard time making his/her answers compatible with surveyjs.io before submitting. Within the answer value itself, there's nothing indicating clearly about the type and inputType of the survey question. (In our case it's a date, not a timestamp.) He/she'll have to look into the survey definition to find out.
  3. Sometimes answers are provided elsewhere, possibly from some app built with surveyjs.io. The value will come in string format and somehow needs to be converted back to DateTime, or not. It's usually hard to tell.