Bubbleのチュートリアル１：Saving data

# はじめに
Bubbleというノーコード/ローコードでアプリを作るサービスがあり、ちょっと言葉に癖があったりするので、チュートリアルをやってみる記録です。Bubble用語は、`Bubble`のように網掛けします。
なるべく細かくキャプチャしていくので、見るだけでもBubbleってこうやるんだと感じていただければ。

https://bubble.io/

# チュートリアルの記録
## チュートリアルの選択
ログイン後のトップページ
＞左メニューのAcademy
＞Learn your way
＞By watching
＞Interactive lessons
＞Saving data

Interactive lessonsは、実際に画面を触りながら、吹き出しとかであれこれ教えてくれるやつです。スマホゲームのチュートリアルをイメージしていただければ。

## デザインページが開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/35dc9948-7787-9073-7c78-3b0716ed5978.png)
左のペインの左端のアイコン（①）で、メイン（③）で操作する内容を選択します。今選択されている一番上は`Design`。デザインとは、ページの見た目をいじること。英語の"設計"という単純な訳より、日本語の"デザイン"に近い意味のデザインというBubble用語です。
②の「Page:index」は、一般的にはアプリは複数ページを持つので、その「index」というページを操作してますよという意味。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/8ae382e6-d1cb-7530-d055-ce9cc6622bbd.png)
ちなみに、Google翻訳してもらいながら進めます。でも、常に翻訳すると、固有名詞も翻訳してわけわからなくなるので、切り替えながら進めます。軽め英語は英語のままキャプチャしていきます。日本語と英語のキャプチャが入り混じりますが、ご了承ください。

このチュートリアルでは、地図上に、場所のセットを表示するアプリを構築するんですね。

Start!


## Seachboxを配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d79f8387-2c39-602b-bd68-c8d005e8172f.png)
入力フォームとボタンを配置するんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/69fbdb66-4a05-644a-3820-224445cfbdc0.png)
`Input`と思ったらそうでなく、`Searchbox`をクリックするんですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/99a1348b-8570-166e-9edd-972194d682a2.png)
クリックしたら、それをページへドラッグすれば表示されるよだって。親切＆丁寧なチュートリアル。
（勝手に`Input`と`Button`をドロップしてたけどそんな雑じゃなかった）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/fb11f3f7-7188-c8ef-ab85-9447447d1941.png)
今ドロップした`Searchbox`が"Input Address"という名前でインスタンス化されて、プロパティ入力画面になりました。左のペインの`Elements Tree`のところに、追加されてます。`Elements`というのは、HTMLの要素１つという感じでしょうか。

Placeholder（入力前の薄い字のやつ）に「住所を入れて」って書く。

「住所を入れて」って書いたら、この入力フィールドはオートコンプリートがなんとかって出たけどすぐ次のステップに行って、キャプチャ撮り損ねた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/0c446809-a6ab-9b1d-cec8-b8d83dde522b.png)
ここをオートコンプリートにしましょう！とのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/86e83033-6bbc-a572-4abf-4f9e8c4380d8.png)
プルダウンを開くと、お、すごい！「Geographic places」という選択肢があった。「Searchbox」って、住所の検索ボックスということか。Google検索とか、ページ内検索とか、そういうことかと思った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/af2be8c1-2dc1-5bee-9f01-96762559e8ed.png)
入力ボックスができたから、位置やサイズを変更してとのこと。

"Feel free to drag it around"で、"自由にドラッグしてね"という意味。英語の勉強になる。（英語リテラシーが低いわたくし）

適当にサイズを変更してContinue。

## ボタンを配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/598a59c1-2bdb-53cc-f601-896b132a5ed2.png)
ボタンを作るために、まず左のペインの`Button`をクリックせよ。

そしてドラッグせよ。（キャプチャ忘れ）
ボタンのラベルをつけよって出たかもしれない。けどそのままにしておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/02139685-6742-9b4f-da10-1ec20f7e21e3.png)
青の吹き出しでは、ワークフローが必要な要素があるよ！と言っているけど、チュートリアルのダイアログでは、放置している模様。この吹き出しはいつも出るのかも。

続く(Continue)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/badc4076-93a8-8226-771d-a67db319165d.png)
Creating new locationsという意味が（日本語でも）わからないけどスルー。'Start/Edit workflow'というボタンではないのはご愛敬。仕様変更にチュートリアルが追い付いていないんでしょう。丁寧に矢印が出るからわかる。ロバスト設計がうまく働いているともいえる。

## ボタンのクリックイベントを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b2f05c0d-e7f3-0ec2-9f14-b2c31fa81b4f.png)
ふとシンプルな画面に遷移し、こんな状態に。左のペインで、上から２つ目の"Workflow"が選ばれている。（さっきは一番上のDesignだった）
つまり、ボタンのクリックイベントを、When Button A is clickedの下の箱で定義していくということか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d6baaf16-ffc9-7c8c-a0bb-3249bf9a6374.png)
なるほど。「for instance」は「例えば」って訳すけど、「など」と訳している。翻訳性能が上がっているってこういうことだな。賢い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/739f4447-7add-cc48-2215-b18dd30dc3a8.png)
`action menu`・・・？イメージがわかない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/0c86eda0-a919-4d07-edd4-b1504a82ce1a.png)
お・・・階層型のメニューが出てきた。そういう意味か。
左の列で「何を使って」、右の列で「どうする」、という感じで、アクションのメニューでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5125e6ce-0702-6dce-d8ff-696e5004557b.png)
毎回矢印が出てくれる。丁寧だ。
`thing`と`data`は同じ意味で使われるようだ。どちらもBubble用語かもしれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/3b380064-5879-90ce-1007-afda634f829b.png)
When Button A is clickedの１つ目の処理のプロパティが、黒っぽいダイアログで出ている。そして次の処理を選択できるように「Click here」がつながっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/00a09d94-1853-dfa5-4ef4-2d6426068326.png)
new typeを作る。`type`とは・・・？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/0aff04cc-15d3-dcb6-c0e1-e17bfc3e7cb1.png)
Locationっていう名前で、型を作ってね、ということか。TypeScriptのTypeのようなイメージで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/0e2ad011-43db-3db6-e52d-62436c502bd9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/211e715b-b541-1529-0cd1-3f8b5edc6ab5.png)
自分で作っておきながら、Locationってなんなんだろう。Locationという名前の型のデータが作られる（たぶん）ことはわかった。でもその型の中身がわからないし、何も入れていないのは気持ち悪い。そのまま続く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/13096b7c-f52b-cb69-c82a-5a200967392d.png)
「Set another field」をクリック。anotherというかまだ空だけど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/cf1e49b1-b5c3-f437-cb1d-79a3a666a497.png)
出た。Bubble独特な入力ボックス。inputの中にbuttonがあるような入力欄です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/be0cdeee-c165-9070-2e05-fb9aa1f6751a.png)
と思ったら、inputの中にinputがある入力欄でした。からのCreate a new fieldで、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/c41d5fdc-522f-a236-6d9a-2d17d05833c3.png)
Createして、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/384e6080-932b-d38e-39ed-a50ea8a93325.png)
Addressという属性名で、型はgeographic addressを選択！すごい型。

とここで少し冷静になって、今作っている`field`という単語はこれ、Bubble用語なので注意。列というかプロパティというか属性というか、それを`field`と呼ぶ。

で、Create。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a37a152b-1e31-2996-b2d0-f384cad9371b.png)
Addressという、Location型の`field`に値を代入です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/c45cd202-8a9b-751b-4eae-482b22682842.png)
個性的な入力ボックスの"Click"をクリックすると、プルダウンが出てきます。`ELEMENTS`のInput Addressを選択。つまり`Design`のところで作った`Element`である`Searchbox`の"Input Address"ですね。それを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/30c14d69-9bfb-7a98-38b8-c527f8d7a70c.png)
"Input Address"`'s value`を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/be6b5d6e-9760-0b4c-bf18-e04e99ef6146.png)
まだ入力できそうだけど、褒められてここで終わり。

ちょっと長くなりましたが、「ボタンのクリックイベントを作成」という作業では、ボタンがクリックされたときに、アクションとして、新しいLocationという`Type`のAddressという`field`に、`Element`である"Input Address"という入力ボックス（&lt;input&gt;）の値を入れる、というところまできました。
つまり、変数に入力ボックスの値を入れたというだけ。
```typescript:TypeScriptっぽく書くと、
funciton handleOnClickButton() {
    type Location = {
        Address: geographic address;
    };
    let loc: Location;
    loc.Address = document.InputAddress.value;
}
```
みたいな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f3d75907-3644-453f-bf3e-0f0873f1155e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/689f4122-ab8d-cbfa-0173-93382932bc49.png)
次の処理は、ボタンを押した後は入力値を初期化する模様。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/1e354762-b9b1-1766-6b99-ce0abcd8e6bb.png)
"Click here"を押すと、メニューが出てきて、`Element Actions`＞Reset inputsを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e4c76e1f-5d50-738c-7578-e935f79cf481.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/497562fa-4511-9766-65a7-410fe26d95a5.png)
あれ、終わった・・・？
設定した変数はどうなったーー（今のところ解なし）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f76d121b-1e6e-14c0-6a68-0445c1ed0d54.png)
`Design`ページに戻るよー

## Maps要素を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/5253338d-573a-5e4c-445a-b37b1d4e4dd2.png)
左のペインの`ELEMENTS`の中から、`Map`をクリックして、画面へ置く。
（１枚キャプチャし損ねた）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/21eb7089-117f-6c38-c21d-1f556e8fe043.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/a88cfe37-f001-146d-dc69-a7abe8a791e0.png)
画面へ置いた瞬間に、ブラウザから、現在位置を取得する要求が、画面から出た通知が出た。なるほど。許可。
そしてチュートリアルが言ってるのは、"Number of markers"（マーカーの数）を`Single`から`List`へ。これは、地図上に風船みたいなマーカーをいくつも出せるようにするという設定か。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/6258b2c7-fcb0-36bd-0efa-7316a3a47cab.png)
マーカーのタイプを、"Location"に。これはさっき作った型・`Type`ですね。`DATA TYPES`というグループに追加されているのがわかります。もともと、"User"という型も登録されている模様。今は使わないけど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b24346b8-d0e7-0c23-bb67-19a2ab92c9d7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f4b1b5e0-2159-487a-dae7-41c0e36d4562.png)
「ユーザーが送信(submit)したすべての場所」。微妙な表現ですが、何度も登録して、マーカーをいくつも置くということ。

"all user-submitted"というのは、"すべてのユーザー"ではなく、"ユーザーが登録したすべての"というニュアンスのために"-"でくっつけてますね。（ちょいちょい英語授業）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/4ba20521-68c3-1e2f-56d9-2ee920bfec0a.png)
Address fieldを開くと、"Address"があったので選択。"Location"という型のどの`field`をAddress fieldと認識するのか、という指定ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/2cfb2b81-2694-20fa-e974-56cd5e844089.png)
`Data source`を指定（？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d537c85b-0078-2e27-74dd-48b77185f65a.png)
`Do a search for`～で、～を検索する。検索する先をこれから指定するよーという選択肢です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/f656c590-e85b-a717-790f-ea6ab072e3ca.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e175f81b-6d70-9358-0e48-61d2f8b323d7.png)
`Do a search for`用のサブダイアログみたいなのが出てきて、また`Type`を聞かれるので、"Location"を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/eee38150-64df-a706-0d1a-b54a82ec60a3.png)
`Data source`の欄に、"Search for Locations"と入っている。（リストで選択された文字でないような顔をして）
そしてサブダイアログみたいなのは閉じないけど次行っていいのかな。

次はMap StyleをGoogle Mapsのデフォルトからちょっと変えるよとのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/4b27b709-64e3-bcf5-d4b4-3c5d767931b3.png)
あ！地図はGoogle Mapが埋め込まれるのか！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d9bea809-79ca-144d-782d-3660c8916443.png)
Map Styleの選択肢、超いっぱいある。Apple Map Styleを選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/69ef862b-844a-e199-a816-096279066bac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/535e7be6-9294-201b-66a6-afc3ae42dfb2.png)
できたっぽい。見た雰囲気はApple Map Styleかもしれないけど、モノはGoogle Mapを使うようです。

これでチュートリアル完成？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/72b16384-c2ff-7c7b-e0f7-5f93ff00bf3c.png)
右上の`Preview`でテスト。

## プレビューで動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/94d27ac0-3bd5-3137-7a7b-55306c70757e.png)
新しいウィンドウが出た。
見た目は、`Searchbox`と`Button`と`Map`があって、あとはテスト用のデバッガツールとかbubbleのコマーシャルとかがついている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/4c1adc58-b84d-31ed-e1ac-9042c2b92a2d.png)
`Searchbox`は、住所用だけあって、住所のオートコンプリートが効いてる。あ、そういえば、`Searchbox`のプロパティで、オートコンプリートがなんか言ってたような・・・あれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/7aa72e0a-4d4d-988d-824b-47868d5bb663.png)
東京タワーと新橋駅と国会議事堂の住所を調べて登録してみた。なるほど。これはGoogle Mapだ。アプリで簡単に使える。すごい。

## 編集画面に戻る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/b2407dd8-d6f7-d129-c241-214b391ab72a.png)
編集画面に戻ると、Saving dataは終わったので、次のをやってね！と書いてありました。
"I'm good for now"（今のところ大丈夫です）を選択すると、ホーム画面へ戻って、あれ・・・そしてアプリケーションを作っていないことになってる！夢だったか。（チュートリアル用に一時的に作って消す仕様のよう）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/e38b2ea6-c507-f565-0ed4-cf537aaa97b4.png)
実は、"Saving data"というのは、`Data`というDBに、`Type`＝DBでいうテーブルを作成する、ということだったと思われます。うすうす、そうじゃないかなーと思いながら進めてたけど、チュートリアル中に別の画面へ飛んで、チュートリアルが台無しになるかもしれないので怖くて触れませんでした・・・。
そして`Data`を見る前に全部消えてしまうという失態。まぁまたやってみようか。復習にもなる。

できたものは消えてしまったけど、次は自分の無料アカウントで作ってるアプリ上の１ページで実装してみようと思いました。
無料アカウントだと、アプリを１つだけ試作でき、そして公開できない、という縛りがあります。でもアプリ内のページは（たぶん）いくらでもできるので、今回の練習用のページも作れます。

# おわりに
あんまり期待せず、そして英語だからわからないかもと思いつつ、チュートリアルをやってみましたが、意外とできました。

Bubble自体のノーコード/ローコードの感触としては、確かに今回のは"ノー"ではありました。でもこの先をチラチラ見ると、JavaScriptはできないといけなさそうだし、エンジニアリングの知識がある程度ないと厳しそう。逆にフロントエンド・バックエンドの概要はわかっている人は、裏の仕組みを想像しながらやると、覚えやすいかもと思いました。
独特なネーミングのせいで、Bubbleでいう～～が、一般的にいう～～と結びつけるのがわかりづらかったり、英語の中に埋め込まれているので、一般単語と固有名詞との区別がしづらかったりするのは、地味に厳しい障壁ではあると、個人的に思います。でもそれは知識だけなので、そこさえ乗り切れば、使いやすいかもしれない。

他のチュートリアルもやってみます。

# 追記(2024/12/19)
## 作り直してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/74fec151-6652-c08e-936e-f38e9744035c.png)
整形して、普通の感じに。
マークがついてるのは、都庁県庁の位置。千葉県庁だけなぜか登録できない。こういうとき、ログがどこに出ているのか。

## 知りたかった`Data`の様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/d1519750-1175-b86a-55c3-8bfd5b005aba.png)
やはり、`Type`を作ることによって"Location"というテーブルができていて、列に"Address"。`Type`はテーブルなんだ。それ以外の４列は、自動で作られるものなので、気にしない。
`Preview`画面で登録していくと、ここにレコードがどんどんできていく。（ちなみにレコードの１件１件は、`entry`と呼ぶらしい）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722610/ca272f94-6448-d506-baac-82f75c2aa81d.png)
そういえば`Design`の`Map`のプロパティで、Data sourceに`Search for` Locations と設定したのは、Locationsテーブルから取り出してねという意味だったことが確定。Search forのサブダイアログで出ていた、`constraint`は抽出条件でDB的に言うとWhere句、`Sort by`はソートでDB的に言うとOrder by句ということでした。
例えば、"ログインユーザー"の列も追加すれば、そのユーザーのLocationだけ取り出す、みたいなことができそうです。

また登録ボタン押下時の`workflow`は、DBへ登録するだけだった。`Map`は、タイムリーにそれを読み取って表示しマーカーを出す。更新ボタンとか押さなくていい。こういうところはノーコードらしい振る舞いな気がする。

ちなみに千葉県庁は、エラーとかではなく"空"でできる。おかしいと思って何度もやると、"空"が何個もできる。こういうよくわからないトラブルのとき、ノーコードだとデバッグが大変。どこから手を付けたらいいのやら。


# Next
次はチュートリアル２に挑戦。
[Bubbleのチュートリアル２：Building a sign-up system](https://qiita.com/yo16/items/1ac9467ad5bb5ed6ba52)