Skip to content

Latest commit

 

History

History
120 lines (81 loc) · 3.34 KB

dart_typed_json.md

File metadata and controls

120 lines (81 loc) · 3.34 KB

Dart typed JSON

This challenge will test how well you understand the Dart type system, as well as your basic JSON syntax knowledge.

Time expectations

For seasoned flutter developers ~ 30 minutes.

For novice flutter developers ~ 5 hours.

Code

To start, paste the following code into an editor.

import 'dart:convert';

void main() {
  String someJson = """{
   "iceCreams": [
      {
         "flavor": "raspberry",
         "color": "red"
      },
      {
         "flavor": "banana",
         "color": "yellow",
      }
   ]
  }""";

  var json = jsonDecode(someJson);

  // (Part 2) should print raspberry
  print(json[0]["flavor"]);

  // (Part 3) how is this even possible?
  print(json["iceCreams"][0].toUpperCase());
}

Part 1

Run the above code. You should see an error that looks like this. Fix it.

Unhandled exception:
FormatException: Unexpected character (at line 10, character 7)
      }
      ^

#0      _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1405:5)
#1      _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:929:13)
#2      _parseJson (dart:convert-patch/convert_patch.dart:40:10)
#3      JsonDecoder.convert (dart:convert/json.dart:612:36)
#4      JsonCodec.decode (dart:convert/json.dart:216:41)
#5      jsonDecode (dart:convert/json.dart:155:10)
#6      main (file:///code.dart:17:14)
#7      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)

Part 2

(line 20) Change the code so that it prints raspberry

// (Part 2) should print raspberry
print(json[0]["flavor"]);

Part 3

This is a bit of an unusual coding challenge because you need to change the code such that does not compile.

If we look at line 23, we see that it calls an undefined method .toUpperCase() on a Map object.

print(json["iceCreams"][0].toUpperCase());

Run your code again. You'll notice that we only discover this issue at runtime -

Unhandled exception:
NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'toUpperCase'.
Receiver: _LinkedHashMap len:2
Tried calling: toUpperCase()
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1      main (file:///code.dart:23:30)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)

Imagine a scenario where we have millions of lines of code, doing JSON parsing in some part, and using the parsed object in another. Keeping track of the type of objects can be a challenge.

Fortunately, the dart compiler has got our back!

Tweak this code such that it takes full advantage of the dart static type system, and this class of human error is rendered impossible.

If you do this right, the dart compiler should spit out a compile-time error that looks something like this -

code.dart:30:31: Error: The method 'toUpperCase' isn't defined for the class 'Map<String, String>'.
 - 'Map' is from 'dart:core'.
Try correcting the name to the name of an existing method, or defining a method named 'toUpperCase'.
  print(json["iceCreams"][0].toUpperCase());
                             ^^^^^^^^^^^