📭

Flutterのデータのモデルについて学んでみる

2022/06/11に公開

Flutterのモデルってどんな仕組みなのか?

Flutterエンジニアやってるのですが、文法への理解が、まだまだないので毎日勉強しております。ドキュメントをあまり読んでなかったのが、文法への理解が浅い原因なのでしょうね😱

参考になる記事

FlutterFireを参考にすることになりますのでこちらを見ます。
FlutterのドキュメントのJSONについての紹介とは別ものですね。似てるから同じと思っていた。FlutterのドキュメントはHTTP通信についての解説みたいですね。
https://firebase.flutter.dev/docs/firestore/usage/

JSONの話題が出てくると、「エンコード」と「デコード」という専門用語が出てくる。何それ?
ITのことを速く理解できる情報が紹介されているWebサイトを参照
https://wa3.i-3-i.info/diff397data.html

用語

エンコードとはデータを他の形式へ変換すること
デコードはエンコードされたデータを元の状態へ戻すこと

Firebaseのデータを扱うときも同じことはしてるみたいですね😅

サンプルコード

// アプリのデータを保存するモデル
import 'package:cloud_firestore/cloud_firestore.dart';

class Diary {
  String? docId;
  Timestamp date;
  String title;
  String review;
  String image;

  Diary(this.date, this.title, this.review, this.image);

  factory Diary.toModel(String docId, Map<String, dynamic> json) {
    final diary = Diary(
      json['date'],
      json['title'],
      json['review'],
      json['image'],
    );
    diary.docId = docId;
    return diary;
  }

  Map<String, dynamic> toJson() {
    return {
      'date': date,
      'title': title,
      'review': review,
      'image': image,
    };
  }
}

toModleとは何か?、fromJsonと同じ意味みたいです。調べても出てこない😅
toJsonとは?

Dartのドキュメント
https://dart.dev/guides/language/language-tour

Flutterのドキュメント
https://docs.flutter.dev/development/data-and-backend/json

翻訳すると

コンストラクターの使用
コンストラクターを使用してオブジェクトを作成できます。コンストラクター名は、またはのいずれClassNameか になります。たとえば、次のコードは、およびコンストラクターを使用してオブジェクトを 作成します。ClassName.identifierPointPoint()Point.fromJson()

var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});

今回は、factoryがついているので、factoryコンストラクターを使ってオブジェクトが生成されています。
つけるとどうなるのか?
インスタンスが生成されなくなるので、そのボディ内でインスタンスを生成して返さなければならない?
返すのは、「return diary」

factory Diary.toModel(String docId, Map<String, dynamic> json) {
    final diary = Diary(
      json['date'],
      json['title'],
      json['review'],
      json['image'],
    );
    diary.docId = docId;
    return diary;
  }

Mapって何か? // こっちはデータの型
map()とは違う! // こっちは関数

Dartの型のドキュメント
https://dart.dev/guides/language/type-system
最近よく見る日本語のサイトも紹介しておきます
https://flutternyumon.com/how-to-use-map/

よく使うMap<String dynamic>の解説を翻訳してみた

型推論
アナライザーは、フィールド、メソッド、ローカル変数、および最も一般的な型引数の型を推測できます。アナライザーが特定のタイプを推測するのに十分な情報を持っていない場合、アナライザーはそのdynamicタイプを使用します。

型推論がジェネリックスでどのように機能するかの例を次に示します。この例では、という名前の変数argumentsが、文字列キーとさまざまなタイプの値をペアにするマップを保持しています。

変数を明示的に入力する場合は、次のように記述できます。

Map<String, dynamic> arguments = {'argA': 'hello', 'argB': 42};

よく聞くアナライザーってなに?

ITの専門用語で測定器のことみたいです。Dartだと文法をチェックしてくれるLinterのことです。
JavaScriptで言うところのESlintですかね...

Dartのパッケージがあるようですね

https://pub.dev/packages/analyzer

型推論に設定する理由はintとかboolとか変更があったときに、対応できるようにするためでしょうね。

調べながら記事を書いていると、factoryコンストラクタで書く理由を見つけました!

https://future-architect.github.io/articles/20220328a/

JSONのを扱うので、こちらの方が相性が良いことから選択するようですね....
Freezedもfactoryって書いてあるところがある🤔
JSONのデータ扱ってましたね!

何故、Map<>と書かないといけないのか?

FireStoreのデータベースの構造は、コレクションが作られると、ドキュメントID(これがKyeになる)が生成され、フィールド(これがvalueになる)が作れる。
なので、データの構造がMap型になってしまう。

スクリーンショット

日付のデータをFireStoreから取得するには、diaryのMap<gEUMg5igtPc7xn3xDLYw, date>こんなイメージですね。間違ってたらごめんなさい🙇

アプリの画面はこんな感じです

記事を書いていてわかったこと

未だに、基本的なことが理解できていなかったのと、この書き方は一つの方法で、今まで違う書き方を見てきたので、あれでよかったのかなと考えてしまう。
今回記事に使ったコードは、優秀なエンジニアさんが教えてくれた書き方なので、良いコードの書き方だと思います。海外のサイトで紹介されているアプリのソースコードを見るとfactoryつけてるの多い気がします。

Discussion