即時関数でつまづいた

ちょっとご無沙汰してました。有村です。
夏が終わろうとしていますね。私は嬉しいです。

さて、今日はJSの即時関数のつまづきについて。先に言っておくと、私はこの子のこと全然理解できてません。
よく分からないなりにも「グローバル領域が汚染されない!」とか「変数や関数が上書かれないからイイ!」とか聞いているので、じゃあそれならとjQueryプラグイン作るときなどに使ってみてます。

そんな中、

のコードで事件は起きました。
「じぇーえすのファイル.js」では、

みたいに、即時関数の中でクリックイベント付与をしています。(本当はもっとあったけど略)
いつもなら、clickは

で囲むけど、今回は即時関数だから実行タイミングを指定しなくてもいいよねと思い、省いた次第でした。

熟練者の方はもうお判りだと思いますが、そうです、この状態でjs_hogeをクリックしてもアラートは出ないんです。
なぜか?それは即時実行されているがゆえ、この読み込みの順番(上から読んでいく)だと「js_hogeにクリックイベント付与するで〜……ってまだDOMが居ねぇ!!」って状態になってしまってるのですよね。
なので、

の順番であれば、ちゃんとクリックでアラートが出ました。

さらに、今度は読み込みの順番はJS → DOMのままで、クリックイベントを $(function(){}); で囲んでみました。

みたいな。
そうしたら、この書き方でもクリックでアラートが出てきました。
なんでだ…と思いましたが、$(function(){}); ってDOMの読み込みが終わったら実行なので、読み込み順がどうあれ動くよってことなんですね。

他にも、即時関数内の関数を外から呼ぼうとして失敗したとか(引きこもりを呼び出そうとして失敗した気持ち)、誰でも使えるプラグインを作るなら $.fn.hoge みたいにjQueryにメソッド追加して外から呼ぶ方がいいのか、定義から実行までひとつの即時関数内で完結させたほうがいいのか、など…。
なんだか久々に「なんで?どうしたらいい?」が爆発した日でした。

それでは、きょうはこのへんで。

composer,npm…すんごい便利なパッケージ依存管理ツール(内容薄め)

私はさっきこう思いました!!

phpunit導入時に超楽させてくれる、composer ←PHP

gulp導入時に楽チンにしてくれる、npm ← JavaScript

 

同じ役割してる!!

原田です。

 

こうやって自分の欲しいもやバージョンを

composer.jsonやpackage.jsonに書けば、それに必要な他のもの・そのバージョンにあったものを自動で取ってきてくれる!!!

{

    “require-dev”: {

        “phpunit/phpunit”: “3.7.*《←導入したいバージョン》

    }

}

 

いちいち、これ使うのにはこれいるとか、調べたり導入する無駄も減りますよね!?

まじ便利というか、助かります!ありがとう!

 

npmとrpmって似てますよね。

rpmもパッケージ管理ツールですよね・・・?

ターミナルでlinux構築の時よく使う気がするけど、ただの手段で使ってるだけでイマイチわかりません!

GASを使ってtrelloとslackを連携させる。

原田です。

 

Trelloとslackを連携させてます!

slackやTrelloの機能で簡単にできることもあるらしいですが、

あえて最近ハマってるGASつくってみました。

GASがあればサーバいらずで便利ですね:D

APIって素晴らしいですねえ!!!

 

・こんなの作る

→Trelloのあるボード内のカードで、期限がその日のものをおしらせしてくれるslackBot

 

・使うもの

slack  /  Trello / GAS

 

・作業

ソースはこんな感じです(ソース汚いのは大目にみてください…)

https://github.com/kin29/Trello—GAS—Slack-/blob/feature-remainder_bot/remainderBot.gs

 

これをトリガー設定で毎日朝に発動させれば完璧です!

 

 

ここで疑問が・・・・・

ってなにしてんだろ?

 

  ↑ 引数のurlにGETリクエストしてるらしい。

 

↑ POSTリクエストしてるらしい。

 

 

・response.getContentText()

取得したコンテンツをとり出しています

 

・JSON.parse()

引数として渡されたJSON文字列をオブジェクトに変換します。

※パース=解析

いまいち、よくわかりませんが、

 

parseしないとjsonデータは特定の文字列を取り出すことができない!

 

ということらしいです。

 

オブジェクトいまいちまだわかんないですね・・・。

オブジェクト指向とかとか・・・

GASでslack bot作ってみた

どうも原田です。

自分を追い込むbotを作ったので、お伝えします。

 

【目的】

一年目というまだ甘えれる貴重な時間をカウントダウンすることにより、惜しみなく勉強させてもらうためのbot

 

【使ったもの】

・GAS(Google Apps Script)

・Slack

たったこれだけ!

 

【作り方】

1.slackのtokenを取得してくる。

スクリーンショット 2016-09-08 17.53.25

自分のアイコン押したら出てくるところの「App & intefrations」をクリック

 

スクリーンショット 2016-09-08 17.57.37

飛んだ先のヘッダーの  「Slack API」をクリック

 

 スクリーンショット 2016-09-08 17.59.09

ナビの「Web API」を選択後、緑ボタンのGenerate test tokensをクリック。

そこにある、「Token」をコピーしとく。➔後で使う

 

2.Googleドライブから新規でGoogle Apps Scriptを作成する。

スクリーンショット 2016-09-08 17.46.42

(デフォルトでは「アプリ追加」で追加しないと入ってないので、入れてください。)

 

3.GoogleApps Scriptにコードを書く。

スクリーンショット 2016-09-08 17.47.04

こんなかんじ

/*
目的:1年目を悔いなく過ごすために、自ら自分を追い込むカウントダウンbotを作成
仕様:土日もbot発動していいと思うので毎日発動する。
文言:「1年目終了まで、あと▲日!」
時間:朝9時
*/
function doGet() {

//2017年3月31日と今の差を求める,カウントダウン
var days = compareDate(2017, 3, 31);
function compareDate(year, month, day) {
var dt1 = new Date(year, month – 1, day);
var dt2 = new Date();
var diff = dt1 – dt2;
var diffDay = Math.floor(diff / 86400000);//1日は86400000ミリ秒
return diffDay;

}
//Slackにpostする
postMessage(days);

}

function postMessage(days) {
var message = “1年目終了まで、あと”+ days +”日のお知らせ”;
var token = “さっきコピーしたToken”;
var channel = “test”; //投稿先チャンネル名
var username = “1年目終了までのカウントダウンbot”; //BOTの名前
var icon_emoji = “:beginner:”
UrlFetchApp.fetch(“https://slack.com/api/chat.postMessage?token=” + token + “&channel=%23” + channel + “&username=” + username + “&icon_emoji=” + icon_emoji + “&text=” + message);
}

 

4.トリガー機能(時計マーク)をつかって定期的に発動させる。

スクリーンショット 2016-09-08 18.35.56

 

5.完成!!!

スクリーンショット 2016-09-08 18.43.28

デフォルト引数

こんばんは。有村です。
風邪ひきましたつらい。今日はちょっと短めで。

PHPに触れたとき、なにこれ読めねぇってなったのがこちら。

fugaはまぁ分かる、引数だよね。で、
fugaのあとの「= 1」って何。
先輩に訊ねてみると、fugaのデフォルトの値のことだよと。なるほどわからん。

改めて調べました。
こいつはデフォルト引数といい、関数を呼んだ際に引数に何も値がなかった場合、こいつをデフォルトで使うよって値らしい。
つまりこういうこと。

うわあ、こいつ便利…。でもJavaScriptでは使えないのよね……………ん??

使えました。

MDN見てたら項目があったので気付きました。ここ
なーんだ、もっと早くから知ってれば良かった!ん?対応ブラウザ?どれどれ…

Internet Explorer → 未サポート
Safari → 未サポート

…よし、解散!!!!

それでは、きょうはこのへんで。

クッキーとストレージでデータを保存!

原田です。

映画「君の名は。」が見たくてたまらないので、大雨の中行ってきます。

 

便利なものを知ったので、ダーっと書きます。

クッキーとストレージ(ローカルストレージとセッションストレージ)の共通点

ブラウザ上でデータを保存し、別のところで利用する機能。

<例>フォームの入力欄で入力してもらったデータを、次のページで使う。

 

「検証」で見ることができます!

スクリーンショット 2016-09-04 12.04.18

見た感じの私の分析では、

クッキーは項目として

Name, Value, Domain, Path, Size, HTTP,…..など結構な項目数あり。

一方、ストレージ(ローカルストレージとセッションストレージ)の項目は

KeyとValueのみ。

 

 

<調べたところのまとめ>

クッキー

  • 有効期限あり。
  • データサイズ 4KB(古い方から削除される。)
  • リクエスト都度、サーバにも送信 →セキュリティ的にもよくない

 

ストレージ

  • 有効期限なし。
  • データサイズ 5KB
  • 通信は発生しない。

→「クッキーの後継技術」と言われているらしい

 

今更ですが、ストレージにはローカルストレージセッションストレージの2つがある。

ローカルストレージ 

ブラウザ内に永続的にデータを保存できるストレージ。

ドメイン:ポート番号」の組み合わせの「オリジン」単位で保存される。

オリジンが同じであれば、ウィンドウやタブ間でデータを共有できる

→ ブラウザを閉じて、再度アクセスしたときでもデータを共有できる。(永続的)

 

セッションストレージ

ウィンドウやタブが開いている間、データを保存し、

ウィンドウ/タブが閉じられると、データは失われる。

ウィンドウ/タブ間では異なるセッションストレージとなり、共有はできない。

 

 

 

 

 

try・catchとif文

こんにちは。有村です。
金曜ロードショーのオール・ユー・ニード・イズ・キル、面白かったです。原作は日本の小説だそうなので、買おうと思います。こうしてまた積み本が増えていく。

今回調べたのは、JavaScriptにおけるtryとcatch
実際にコードとして書かれているのは見たことがありましたが、なぜ今まで関わろうとしなかったかというと、説明をいくら読んでも分からなかったから。
「例外の処理」って言われても、例外をはじきたいならif文があるやん?特に困ってないし必要ないんじゃない?と思っていたのですが。
MDNの「初心者向け・JavaScriptガイド」にtry・catchが出ていたので、脱☆初心者するために調べてみることにしました。ううう。

①ifで定義できないエラーだってあるのよ
ネットで調べていてなるほどと思ったのが、Ajaxのレスポンス値を$.parseJSONするときの例え。
$.parseJSONするときに、改行が混ざっていたり、文字列がダブルクォートで囲まれていなかったりすると、パースに失敗します。
渡す値が必ず「正確なJSON形式の文字列」であることが分かっているならよいのですが、それを事前に精査することってムズカシイ。
さらにAjaxのレスポンス値であれば、その値は毎回変わる可能性が非常に大きいですよね。中が空という状態もあり得るわけです。これもパースに失敗します。
なので、この場合は「もし文字列に特殊文字が含まれていたら」「ダブルクォートで囲まれていなかったら」「そもそもレスポンスが空だったら」がエラーになる条件になりそうですが(もっと多いかもしれないけど)、それをif文で書くなんて無理。
なので、try・catchで「try中の$.parseJSON処理でコケたことを検知したら、catch処理に移る」というコードが最適解なのですね。なるほど。

②try・catchは先に進める
JSは、処理中にエラーが発生した場合、処理がそこで止まってしまいます。
なので、その先に別の処理があったとしても、それが実行されることはないのです。
try・catchは、try内でエラーが起きたらcatchの中に入り、さらにその先へと進むことができます。

もしここでtry・catchを使っていなければ、「ここまでこれるよ」のテキストは表示されません。
こんな使い方もできるそうです。

これは、エラー時の処理は特に指定せず、エラーが起きても処理を先に進ませるための記述のようですね。

有村的まとめ
if文で「もしhogeが”10″ではなかったら」などの分岐を書いても例外処理はできますが、ifの範疇に収まることができないもの、そもそも
予測が難しいものがあります。
他の言語の話かもしれませんが、「回線が切断された」「DBの接続が途中で切断された」などの場合もtry・catchを使うそうです。確かにこのような外部起因の問題はif文では制御のしようがありません。
なので、
if文は事前予測が可能で、コードとして事象を表すことができるとき
try・catchは事前予測が困難で、エラー発生時も処理を継続、もしくはエラー時処理が必要なとき
に使うというのが、ひとまずの落としどころでしょうか…?

猫が遊んでくれとPCの周りうろちょろして邪魔するので、これにて一旦完結です。
それでは、きょうはこのへんで。

JOINで結合してみた

こんばんは。有村です。
トムヤムクン食べたいです。(夏バテ)
原田さんが元気で羨ましい。

今日は、聞いたことはあったけど避けて通っていた領域…SQLの結合について分かったことを書きます…!

でーたべーすなんじゃらほい?からスタートした私は、SELECT・FROM・WHEREと聞くだけで全裸で逃げ出したくなるレベル。
が、ついに「1つのテーブルだけじゃ思ったように結果を出せない…このテーブルとこのテーブルをくっつけた結果が欲しいな…」という、結合をしないと詰む事態に遭遇してしまったのです!

問題のテーブルたちは、例えばこんな感じ。

=================
【商品情報】
ID 商品名 カテゴリID
1 コート 1
2 半ズボン 3
3 靴下 9

【カテゴリ情報】
カテゴリID カテゴリ名
1 はおりもの
2 小物
3 ズボン
=================

欲しいのは、商品IDと商品名とカテゴリ名。
商品情報テーブルでもカテゴリの情報を持ってはいますが、そこにあるのはカテゴリの「ID」だけ。
カテゴリIDを見ただけで何か分かればいいですけど、私は分かりません。
ので、商品情報テーブルのカテゴリIDをもとに、カテゴリ情報テーブルのカテゴリ名を引っ張ってこれないかな?と考えました。

で、教えてもらったのがこちら。

SELECT 商品情報.商品ID, 商品情報.商品名, カテゴリ情報.カテゴリ名 FROM 商品情報 LEFT JOIN カテゴリ情報 USING(カテゴリID);

思ってたよりあっさり!

ポイントはLEFT JOINUSING
先ほど書いたSQL文を有村なりに訳すと、
「商品情報テーブルにカテゴリ名がないから、カテゴリ名を持ってるカテゴリ情報テーブルをがっちゃんこするわ〜。対象のカラムはカテゴリIDな。で、それが終わったら結果としてIDと商品名とカテゴリ名をくれ」
なのかなと思います。実行結果はこちら。

=================
【結果】
商品ID 商品名 カテゴリ名
1 コート はおりもの
2 半ズボン ズボン
3 靴下 null
=================

靴下のカテゴリ名がnullになっていますが、これは靴下のカテゴリIDである「9」に対応するレコードが存在しないためです。
また、USINGについては、がっちゃんこするカラム名同士が一致していないと駄目みたいです。今回は、商品情報テーブルの「カテゴリID」とカテゴリ情報テーブルの「カテゴリID」を使ったため、USINGが使えたのですね。
もしそれぞれが異なる名前であれば、USINGの代わりにONを使います。

JOINひとつとっても、INNER JOINとかRIGHT JOINとか他にもあるみたいです。
用途に応じてどれを使うか変わってくるそうなので、色々試してみます!

それでは、きょうはこのへんで。