はじめに
前回作ったタイマーアプリにFirebaseを上手いこと実装していこうと思います。
✅ゴール
・FirebaseでCRUD実装
・非同期処理で上手く処理する
設計
Firebaseを交えてアプリ制作をするにあたって、そもそもどういう処理を実装したいのか考えないと着地点が見えなくなると思ったので設計。
✅機能
・タイマー機能(スタート/ストップ/ラップ/リセット)
※ラップは上から1,2,3と表示に変更
・ラップ毎に学習したことをメモできる。
・保存ボタンで保存した後ツイートするか選択できる。
※スタートボタンが押されたら表示する(ラップが3つ以上なくても動作するように変更)
※前回は簡単ツイートアプリに移動していたのを直接ツイッターに移動できるようにする。
・次回に向けた課題の登録ができる。前回登録した課題を表示する。
JSの変数に変数を使用する方法(eval関数の理解)
※推奨されていないみたいなので不採用になりました。
リファクタリングで威力を発揮しそうだったので勉強。
参考:MDN
eval()関数は、文字列として表現された JavaScript コードを評価する。
参考:JavaScriptで可変変数を作る方法を現役エンジニアが解説【初心者向け】
なかなか理解しづらかったですが、eval関数で可変変数が作れます。
for (var i = 0; i < 1; i++) { console.log(i); // 0 eval("var n" + i + "=" + i + ";");// var n + 1 = 1; console.log(n0); // 0 eval("console.log(n" + i + ");");// 0 }
var a = "aaa"; var b = {}; b[a] = "bbb"; console.log(b[a]); //bbb console.log(b.aaa); //bbb
eval関数を使わずにオブジェクトを使う場合はこうなる。
🙄個人的にはevalがわかりやすいな。ただセキュリティ上、注意が必要らしい。
参考:Eval: コード文字列を実行する – 現代のチュートリアル
varでは実行できるのにletで宣言するとエラーになると思っていたら、
strict モードでは、evalは独自のレキシカル環境を持ち、eval 内で宣言された関数や変数は外側では見えないとのこと。
🙄ここからもevalは現在、推奨されていないことがよくわかります。。。
JSファイルの分割
index.jsファイルが冗長になって使いづらいのでファイルを分けます。
モジュール化も考えたもののES6の実行環境とビルドの手間を考えて一旦ファイル分け、HTML上で読み込む順番を配慮して実装していきます。

👆の感じで使い勝手を検証してみます。
ツイートボタンの実装
※この後ツイートボタンから保存ボタンに即変更しました。笑
先日URLでツイート文を渡す方法は知っていたのでこれは楽でした。
改行は%0a、ハッシュタグは%23で渡せるのを知っていれば◎
また、以下の感じで定義すると\n使う必要がなくなるのと、クォーテーションと+での連結地獄を避けられることに気付きました(今更感)。
let createText = `学習時間:${report.value} 学習したこと ・${memo1.value} ・${memo2.value} ・${memo3.value} ※#1~#3の3つ登録できます 次回の課題${task} OKでTwitter画面に遷移します`;
🙄こっちの方が随分と見やすいですね!!
同じくこれを
let urlText = '学習時間:'+ report.value + "%0a学習したこと%0a・" +memo1.value + "%0a・" +memo2.value + "%0a・" +memo3.value +"%0a%23駆け出しエンジニアと繋がりたい%0a%23プログラミング学習%0aPost:https://chobimusic.com/timer";
こうする
`学習時間:${report.value}%0a学習したこと%0a・${memo1.value}%0a・${memo2.value}%0a・${memo3.value}%0a%23駆け出しエンジニアと繋がりたい%0a%23プログラミング学習%0aPost:https://chobimusic.com/timer`;
スッキリして嬉しい!!
そして今更関数をグローバルに定義することを覚えました。
let tweetFunction = (createText, urlText) =>{ if (window.confirm(createText)) { let href = "https://twitter.com/intent/tweet?text=" + urlText; open(href, "_blank"); } }
こうすることでif文の中からtweetFunctionで関数を呼び出すことができますね!!
保存ボタンの実装
ツイートボタンを保存ボタンに変更。
ラップが3つ作成されるとツイートボタン表示3させていたのを、1つもなかった場合~3つ以上の場合で条件分岐で実装。
※可変変数の作り方がわからず要改善ポイント。
✅firebaseにテキストを保存
良いのか悪いのかインデントが反映されてしまいます。

とりあえずコード側でインデントをなくしました。

🙄見栄えが。。。

※firebase上はいい感じですね!
テキストだけ丸丸保存して正規表現で取り出し、描画にするか最初から取り出しそうな部分も別途名前を付けて値を保存するか悩む。
一旦以下の形で使い勝手を検証していきます。
db.ref('/').push({ order:Date.now(), date:dat.toLocaleDateString(), time: report.value, txt: mktxt, task: task, }
🙄今回はpushメソッドでURLに依存しない一意の値を保存できるようにしました。
制作中の画像だけどこんな感じ。

ここでfirebaseのデータ数を取得したらIDも指定できると気づく。
参考:JavaScriptの連想配列の要素数を取得する方法を現役エンジニアが解説【初心者向け】
Object.keys().lengthでオブジェクトの数は取得できました。
let lenDB = Object.keys(getDB).length;
firebaseから値を非同期で取得
非同期でfirebaseから値を取得して、取得後、取得した値の出力と値の数を変数に代入する。
function l(e) { return console.log(e); } ~~~~ function async(){ return new Promise((resolve, reject) => { db.ref('/').on('value', (snapshot) => { getDB = snapshot.val() if (getDB !== null ){ resolve(getDB); } else { reject("firebaseのデータ取得に失敗"); } }); }); } // コールバック関数でthen(成功時の処理,失敗時の処理) async().then( res => { l(res) lenDB = Object.keys(getDB).length; l(lenDB); }, error => { l(error); } );
その他微調整したところで今回は終了。

🙄だいぶそれっぽくなりました。
躓いた点
✅confirmで未入力でもOKおすと変数が””で定義される。
⇒null/undefinedではないのでfirebase上にもtask:””と書き込まれてしまう。
おわりに
しっかりasync Functionも理解していきたい。
前回作ったツイートとディレクトリ分ければよかった。。。
gitにpushしづらい。。。
次回は合計時間や詳細を表示してくれる記録ページ、できればログイン機能を実装していこうと思います。
備忘録
VSCodeの出力で白は文字型、黄色は数型。
✅効率化
document.getElementByIdを短縮する方法
これ感動しました。
function $(e) { return document.getElementById(e); } let $ = (e) => { return document.getElementById(e); } // これのどっちか。 let startBtn = $('startBtn');
で超短縮できる!!!これに関してはアロー関数使わないほうが見やすいかも??
調べたらありました。めちゃ便利!!以下修正したもの(結構思いきりました。)。
大文字と小文字注意!!!
reference ⇒ ref
Element ⇒ Elem
create ⇒ mk
text ⇒ txt
hidden ⇒ hdn
number ⇒ num
pass ⇒ ps
count ⇒ cnt
Hour ⇒ H
Min ⇒ M
Sec ⇒ S
start ⇒ stg
wrap ⇒ wrp
reset ⇒ rm ※削除ボタンがないことを考慮
コメントを残す