Article: How to JSON with Flutter#773
Article: How to JSON with Flutter#773sethladd merged 11 commits intoflutter:masterfrom roughike:json-tutorial
Conversation
|
|
||
| Next, define some build actions. | ||
|
|
||
| #### Defining the build actions |
There was a problem hiding this comment.
FYI – this has been simplified a lot.
See https://github.com/dart-lang/json_serializable/tree/master/example
There was a problem hiding this comment.
Great! I'll look into it and update this section.
There was a problem hiding this comment.
I tried to take a quick look into it, and ran into the exact same issue that this reddit user describes in this comment.
This is reproducible on the latest Flutter version, and happens by simply following these steps:
- create a new Flutter project
- add the dependencies listed on the
json_serializableexample README you just linked - attempt to get the packages -> a long error message which states that a version
^0.7.0forbuild_runnerwas not found.
Should I create a more detailed issue report, or is this some common issue that can be resolved easily?
There was a problem hiding this comment.
We're in dependency lock, I'm pretty sure.
I think I have a path to untangle the knot (at least a bit). Follow here: google/json_serializable.dart#95
| <li><a href="/platform-channels/">Platform-specific code</a></li> | ||
| <li><a href="/reading-writing-files/">Read and write files</a></li> | ||
| <li><a href="/networking/">Network and HTTP</a></li> | ||
| <li><a href="/json">Serializing JSON objects</a></li> |
There was a problem hiding this comment.
maybe more simply: "JSON and serialization"
| permalink: /json/ | ||
| --- | ||
|
|
||
| It is hard to think of a mobile app that doesn't need to communicate with a web server at some point. When making network-connected apps, chances are that we need to consume some good old JSON, sooner or later. |
There was a problem hiding this comment.
global: please line break at 80 chars
|
|
||
| It is hard to think of a mobile app that doesn't need to communicate with a web server at some point. When making network-connected apps, chances are that we need to consume some good old JSON, sooner or later. | ||
|
|
||
| In this tutorial, we look into ways of doing JSON with Flutter. We will go over what JSON solution to use in different scenarios and why. |
|
|
||
| Where the manual serialization does not perform well is when your project becomes bigger. Writing the serialization logic by hand can become hard to manage and error-prone. If you have a typo when accessing an unexisting JSON field, your code throws an error during runtime. | ||
|
|
||
| If you do not have many JSON models in your project and are looking to test a concept quickly, manual serialization might be the way you want to start. |
There was a problem hiding this comment.
link down to the example section. For example: "To learn more, and to see an example, jump to ___________"
(global comment, link to each example from these intro paragraphs)
| You might want to use generated code for JSON serialization when you have a medium or a larger project. | ||
|
|
||
| ## Is there a GSON/Jackson/Moshi equivalent in Flutter? | ||
|
|
There was a problem hiding this comment.
Answer the question immediately, and then provide the background :)
There was a problem hiding this comment.
it's hard to tell: yes, or no
|
|
||
| Dart has supported _tree shaking_ for quite a long time. With tree shaking, we can “shake off” unused code from our release builds. Tree shaking allows us to optimize the size of our applications significantly. | ||
|
|
||
| While Dart users might have gotten used to [dartson](https://pub.dartlang.org/packages/dartson) to (de)serialize their JSON, it does not work with Flutter. The reason behind this is that `dartson`, like [GSON](https://github.com/google/gson) in Java, uses _runtime reflection_. In Flutter, reflection (also known as `dart:mirrors`) is disabled. |
There was a problem hiding this comment.
I might make this paragraph more of an aside. It's probably not relevant to most users. Can you make it an aside, and get to one sentence? e.g. "What about dartson? ____________"
|
|
||
| ## Serializing JSON manually using dart:convert | ||
|
|
||
| Basic JSON serialization in Flutter is very simple. Dart comes with the `dart:convert` library built in, and using the JSON decoder API is straightforward. |
There was a problem hiding this comment.
"comes with" and "built in" are redundant
There was a problem hiding this comment.
maybe: "Flutter has a built-in 'dart:convert' library, which includes a straightforward JSON encoder and decoder."
|
|
||
| Basic JSON serialization in Flutter is very simple. Dart comes with the `dart:convert` library built in, and using the JSON decoder API is straightforward. | ||
|
|
||
| Let's say we need to deserialize a JSON representing a user object. For sample purposes, we have a real simple JSON model. |
There was a problem hiding this comment.
"Here is an example JSON for a simple user." to replace the second paragraph
| String name; | ||
| String email; | ||
|
|
||
| User.fromJson(Map<String, dynamic> json) |
There was a problem hiding this comment.
should we not put the constructors together?
| class User { | ||
| User(this.name, this.email); | ||
|
|
||
| String name; |
|
|
||
| ```dart | ||
| Map map = JSON.decode(json); | ||
| User user = new User.fromJson(map); |
There was a problem hiding this comment.
s/User user/var user (since it's obvious
| Now the calling code does not have to care about the serialization logic. With this new approach, we can deserialize a user quite easily. | ||
|
|
||
| ```dart | ||
| Map map = JSON.decode(json); |
There was a problem hiding this comment.
is there a better variable name for map ?
| String json = JSON.encode(user.toJson()); | ||
| ``` | ||
|
|
||
| While with this new approach the calling code does not have to worry about JSON serialization at all, the model class still definitely has. In a production app, we would want to be sure that the serialization works. In practice, this means that the `User.fromJson` and `User.toJson` both need to have unit tests in place to verify correct behavior. |
There was a problem hiding this comment.
this first sentence was hard to parse.
|
|
||
| The `json_serializable` package is an automated source code generator that can generate the JSON serializing boilerplate for us. | ||
|
|
||
| Since the serialization code is not handwritten and maintained by us anymore, we minimize the risk of having JSON serialization exceptions at runtime. If the sources are generated, and the app compiles, we should be fine. |
There was a problem hiding this comment.
I think this second sentence is redundant.
|
Fantastic! Thank you so much. |
|
Incorporated the first feedback round. Waiting for @kevmoo to resolve google/json_serializable.dart#95. Once I can test the simplified way of using |
…would degrade in readability if fixed.
| } | ||
| ``` | ||
|
|
||
| We can run the watcher by doing `dart tool/watch.dart` in our project's root |
There was a problem hiding this comment.
As @kevmoo said in this comment, seems like these sections are going away completely. With the new simplified version of json_serializable, there's no need for manually configuring build actions, watchers and build files. Correct me if I'm wrong.
So, should I:
- wait until Fix workflow w/ flutter and json_serializable v0.3.1 google/json_serializable.dart#95 gets resolved and replace these old instructions with new ones, or:
- fix these issues now, publish this article with the old instructions, then update with new
json_serializablesection once Fix workflow w/ flutter and json_serializable v0.3.1 google/json_serializable.dart#95 is resolved?
It's your call @sethladd. I'm fine with either way!
There was a problem hiding this comment.
if google/json_serializable.dart#95 is less than a week away, then let's wait.
If it's more than a week, let's publish this article now, as long as you're OK with updating it "soon".
@kevmoo what's the ETA?
There was a problem hiding this comment.
As of Flutter latest, everything seems to work – flutter/flutter@6e38b42
It's all about the very tight dependency constraints on packages in flutter & flutter_test
There was a problem hiding this comment.
Pretty sure we'll want to delay the new documentation until that change is rolled to the alpha branch, which most people are using by default?
(BTW, I have not abandoned this. I would love to do as many feedback rounds as it takes to publish the article, but I'm very busy this week.)
| ``` | ||
|
|
||
| We can run the watcher by doing `dart tool/watch.dart` in our project's root | ||
| folder. It is safe to start the watcher once and leave it running in the |
There was a problem hiding this comment.
please provide an example of how to run this. (it's not obvious how to use the command-line Dart VM that is bundled with Flutter.)
| ``` | ||
|
|
||
| Now we can generate all the necessary JSON serialization source files by running | ||
| `dart tool/build.dart` in our project's root folder. While the build file is all |
There was a problem hiding this comment.
this assumes you have the Dart SDK installed separately from Flutter. Instead, please show how to run the command-line Dart VM that is shipped with the flutter SDK.
There was a problem hiding this comment.
Here's how to do it: https://groups.google.com/forum/#!topic/flutter-dev/xoS0WSUax8Q
|
Just for my own purposes (to make it easier to see what's going on when I go through all the open PRs):
BTW, thanks for your contributions @roughike ! Much appreciated. |
|
This should be unblocked now, we just rolled dev. |
|
Great! I'm getting back to Finland in 12hours or so, I'll finish the changes once I wake up and recover from the jet lag. I'll do the "what if I decode lots of JSON and the UI lags" part as well. |
|
Can confirm. With Flutter 0.0.21, you can get all of the latest/greatest
build tools
…On Tue, Jan 30, 2018 at 8:00 AM, Iiro Krankka ***@***.***> wrote:
Great! I'm getting back to Finland in 12hours or so, I'll finish the
changes once I wake up and recover from the jet lag. I'll do the "what if I
decode lots of JSON and the UI lags" part as well.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#773 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AABCimZWt1HwoVbkbsJTjXEmkU8vjNeVks5tPzyxgaJpZM4RTLlz>
.
|
…rts of the article.
|
Here's what I found about the "avoiding blocking the UI when decoding lots of JSON" that we discussed in the afterparty:
I guess the culprit could be passing a huge string (raw JSON) to the |
|
I'm pretty sure no one would request 15 000 objects from a backend API at once, but they would implement paging instead. Given my findings, should we still do the section about the "not blocking UI when deserializing"? I'm completely fine either way :) |
| --- | ||
|
|
||
| It is hard to think of a mobile app that doesn't need to communicate with a web | ||
| server at some point. When making network-connected apps, the chances are that |
There was a problem hiding this comment.
server, or easily store structured data, at some point
|
|
||
| ## Which JSON serialization method is right for me? | ||
|
|
||
| There isn't a one size fits all JSON solution for every project. |
There was a problem hiding this comment.
Add a short paragraph here:
This article covers two general strategies for working with JSON:
- Manual serialization and deserialization
- Automated serialization and deserialization via code generation
| us. Luckily, there is! | ||
|
|
||
| <a name="code-generation"></a> | ||
| ## Serializing JSON using json_serializable |
There was a problem hiding this comment.
mention: code generation here (as we talk about it above as "code generation" and that's more what people are looking for. They don't know what json_serializable is , at this point)
For example: serializing JSON using code generation
sethladd
left a comment
There was a problem hiding this comment.
Overall, looks great!
A couple of small comments.
Lets address the small comments, merge this article. And then lets add a new section called "working with JSON on another thread"
Thoughts?
|
cc @kevmoo to double-check the json_serializable bits of the article. we're about to commit. |
|
Latest feedback addressed.
Agreed. I was thinking of including that new section with this PR, but let's ship this as soon as this is ready. This has already been sitting one month, sorry about that :) I'll write about that "working with JSON on another thread" in a separate PR. |
|
Hey @sethladd and @kevmoo, would it make sense to ship a live template with the Flutter / Dart plugin to make using Something like this: An even crazier idea would be having a squiggly red line under the class name saying "Code not generated yet". By pressing Alt-Enter, an option saying "Generate code for json_serializable model" would appear. By hitting enter, the following steps would be done:
From the user point of view, all they had to do was write "json", press enter, press Alt-Enter and now they have working |
|
@roughike that's really cool! I encourage you to open a new issue for that feature request. That way, we can think about how to do it for both VS Code and Android Studio. |
|
Other than that, thank you! LGTM from me. Pending LGTM from @kevmoo |
|
@sethladd What's the correct repo to open that issue? flutter-intellij would be my first guess, but don't know if it's related to Dart analysis server and just disabled on plain Dart projects. :) |
kevmoo
left a comment
There was a problem hiding this comment.
Small tweaks, but otherwise LGTM
|
|
||
| <!-- skip --> | ||
| ```dart | ||
| String json = JSON.encode(user.toJson()); |
There was a problem hiding this comment.
toJson is not needed here. JSON.encode calls toJson for you!
| : name = json['name'], | ||
| email = json['email']; | ||
|
|
||
| Map<String, dynamic> toJson() { |
There was a problem hiding this comment.
Would probably use => notation here.
Map<String, dynamic> toJson() =>
{
'name'
...There was a problem hiding this comment.
I can definitely change it, but the original reasoning for me going the long route was that dartfmt always formats it like this:
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};Which in my eyes didn't look as pretty.
| ## Serializing JSON using code generation libraries | ||
|
|
||
| Although there are other libraries available, in this tutorial, we use the | ||
| [json_serializable package](https://github.com/dart-lang/json_serializable). It |
There was a problem hiding this comment.
Link to the package site - https://pub.dartlang.org/packages/json_serializable
|
|
||
| <!-- skip --> | ||
| ```dart | ||
| String json = JSON.encode(user.toJson()); |
There was a problem hiding this comment.
ditto about not needing .toJson() here
…zable link to be a Pub one.
|
Not a biggy either way...
…On Wed, Feb 7, 2018 at 1:31 PM, Iiro Krankka ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In json.md
<#773 (comment)>:
> +
+**user.dart**
+
+<!-- skip -->
+```dart
+class User {
+ final String name;
+ final String email;
+
+ User(this.name, this.email);
+
+ User.fromJson(Map<String, dynamic> json)
+ : name = json['name'],
+ email = json['email'];
+
+ Map<String, dynamic> toJson() {
I can definitely change it, but the original reasoning for me going the
long route was that dartfmt always formats it like this:
Map<String, dynamic> toJson() => {
'name': name,
'email': email,
};
Which in my eyes didn't look as pretty. :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#773 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AABCissPH5r5QY0bL8728uMbY-nfRclVks5tShYZgaJpZM4RTLlz>
.
|
|
I'm ready to merge. I'll create the issue tomorrow and open a new PR about "serializing JSON on a separate thread" when I can! |
|
Nice, thanks! |

Fixes flutter/flutter#13520.