モダンなJSの話──アロー関数

こんにちは。イノベーター・ジャパン(以下、IJ)のエンジニアのbmfです。 今日はフロントエンド界隈の方からすると今更感のあるネタかもしれませんが、ES2015から追加されたアロー関数についてかきます。

アロー関数ってなに?

ざっとまとめると、

  • ES2015から追加された新しい構文
  • 通常のfunction式よりも短くかける
  • thisの値を語彙的に束縛することができる(=文脈からthisの値を把握しやすい)
  • 常に匿名関数

アロー(=>)を使ってかく関数式で、"thisの値を語彙的に束縛することができる“という点が大きなポイントです。

アロー関数を使うと、今までこう書いていたものが・・・

const foo = function() {
  console.log(this);
}

foo();

こんな感じでかけます。

const foo = () => {
  console.log(this);
}

foo();

ちなみに、引数を取らない場合は丸括弧()が必要で、引数を1個しか取らない場合は丸括弧は任意です。

// 引数がないときは丸括弧必須
const foo = () => {
  console.log(this);
}

foo();
// 引数が一つしかないときは丸括弧は任意
const foo = (value) => {
  console.log(value);
}

foo('Hello!');

即時関数にしたい場合はこんな感じでかけます。

(() => {
  console.log('Hello!');
})();

これはちょっと混乱しそうですね・・・

使いドコロ

使えるところは積極的にアロー関数に置き換えていく方針で良いかと思いますが、thisが何を指すのかだけは意識しておいたほうがいいです。

例えば、下のようなケースの場合はどうでしょうか。

const objA = {
  value: 'foo! foo!',
  sayHi: function() {
    console.log(this.value);
  }
}

objA.sayHi();

const objB = {
  value: 'bar! bar!',
  sayHi: () => {
    console.log(this.value);
  }
}

objB.sayHi();

1つ目のthisはオブジェクト内のvalueを、2つ目のthisはグローバルオブジェクトを返します。 このようなケースを見ると、function式とアロー関数式を使い分ける必要性があるケースもいくつかあるような気がします。

JavaScriptのthisの詳しい話はMDN - thisをご参考ください。 “thisの値が何を指すのか"を理解しておくとよりアロー関数への理解、JSへの理解が深まります。

まとめ

Vue.jsやらReactやらフレームワークを使っているとコード量が多くなりがちだったり、thisがあっちらこっちら散らばって何がなんやらという状態になりやすい気がします。 アロー関数を使って関数部分をシンプルに記述することができれば、コードの見通しも良くなると思います。

参考

PHPカンファレンス福岡2017で Payment Request API の話をしてきました #phpconfuk

こんにちは、 @gorou_178 です。 先日6/10のPHPカンファレンス福岡2017で登壇しました。Payment Request APIをAPI型決済サービスとからめてお話させていただきました。

続きを読む

PHPカンファレンス福岡2017でDockerと自作Webサーバについて話しました。 #phpconfuk

こんにちは、2017年6月1日よりイノベーター・ジャパン(以下、IJ)の東京オフィスにジョインしました @hanhan1978 です。

※本エントリはカンファレンス報告に、シレッと入社報告エントリが混ざっています。

まずはカンファレンス報告から。

PHPカンファレンス福岡2017

2015年時から3年連続で登壇者として参加していました。控えめにいって、今年も最高でした。今回の発表は2本。

Dockerを本番で使ってみて分かったこと

本番リリースまでに検討するべき内容を自分なりにまとめて見ました。頭で想像していたより遥かに大変だった箇所が沢山あったので、今後Docker導入する方たちにとって、良い参考になればと思います。

PHPでWebサーバを作ろう

2つ目は、LTの一発目でした。PHPを使っていると、Socket通信を行うようなコードを書く機会は少ないと思います。通信やIOをきちんと考える必要があるコードは、勉強にはもってこいなので、参考になったらなと思い発表しました。ちなみにソースコードは下記です。(ちゃんと動きますよ!) https://github.com/hanhan1978/phpconfuk2017_demo

運営について

弊社からも運営メンバーが参加していましたが、登壇者側の視点から見ても、参加者側の視点から見てもほとんど不満はありませんでした。迷うようなところもありませんし、セッションの数やペースも適切だったと思います。

Ask The Speakerがあるおかげで、セッションの残り時間を気にすることなく突っ走れるのは、良いアイデアだなと思いました!

↓↓↓以下、入社報告エントリー ↓↓↓

入社したきっかけ

前職の退職が決まった後に、ちょうど同じ勉強会に参加していた @yamacho1111 さんにお会いして、誘われたのがきっかけでした。

IJの方々が、カンファレンス開催・参加などに積極的であることは分かっていました。それにLaravelといえば @localdisk さんだよねという実力のあるエンジニアがいることももちろんですが、やはりジョインの最大の理由は「オジサンが結構いる!」です。

同じオジサンとして、スキルの高いオジサン仲間がいるのは本当に心強いです。ここなら心置きなく頑張れそうな気がしました。(割りと本気で…)

これから

まだ、入社して10日も経ってないので、会社のアレコレを語れる感じではないですが、PHP系のカンファレンスに多数参加していることもあるので、既存アプリも新規アプリも外に出しても恥ずかしくないPHPウェブアプリにして行きたいと思います。

以前と変わらず、今後もカンファレンスや勉強会へも積極的に参加して行きますので、どこかで見かけた際はお気軽にお声がけ頂けたらと思います。

余談ですが、確かによく見かけるアイコンばかりです!(下記)

これからもよろしくお願いいたします!

イノベーター・ジャパンに入社したぞ @bmf_san

こんにちは。イノベーター・ジャパン(以下、IJ)のエンジニアのbmfです。 2017年5月1日より入社しました。どうぞよろしくお願いします。

まだ入社して一ヶ月も経っていないのですが、入社エントリを書きます。

経緯

大学卒業後はフリーランスのwebデザイナー、コーダーを、前職ではスタートアップで何でもやる系エンジニアをやっていました。 約2年間ですが、体力的にも、精神的にも、技術的にも今後のエンジニアライフの礎になりそうな部分が鍛えられたと思っています。 新卒3年目という節目にあたり、エンジニアとして大きくステップアップを図ろうと、IJに入社し、現在に至ります。

IJでは、ビジネスをデザインするエンジニアとして、「技術で課題を解決していくこと」にコミットしていけるよう努めていきたいと考えています。

入社のきっかけ

IJ主催で開催されていた勉強会を通じてIJを知りました。

tech.innovator.jp.net (さりげなく写真に映っていました。IJとの邂逅。)

転職活動時にずっと気になっていたIJのことを思い出し、ブログやイベント、SNS、面接を通して、「非常にオープンな会社であること(外部に向けて情報発信している方が多い!)」「人間関係が良さそうなこと」「エンジニアとして色々な挑戦を許容する文化がありそうなこと」から入社を決めました。 それからLaravelにとても詳しい光エンジニアの方がいらっしゃるということも・・・!

入社してみて

入社前と入社後でギャップに感じていることは今のところは特にありません。 オフィス環境の快適さ社内のオンライン・オフラインのコミュニケーションの豊かさ社員それぞれのやりたいこと目標を尊重する文化等良いなぁと思うところがたくさんあります。 まだまだIJの光の部分、闇の部分見えていないところがあるかもしれませんが、私は元気です。

これから

まだまだヒヨッコの身なので毎日修行の日々ですが、沢山経験を積み、社内外問わず幅広く活躍していきたいと思っています。f:id:bmf-dev:20170528184620j:plain(ヘドバンにすべてを捧げていたクレイジーだった頃の写真。悪魔にとりつかれているの図。)

EloquentのHasOneリレーションで関連先がないと null になる問題の対処方法

こんにちは。エンジニアの @localdisk です。タイトルの件、最近まで自分も知らなくてマニュアルにも載ってないのでブログに書くことにしました。

f:id:localdisk:20160824143945p:plain

具体的にどういうこと?

たとえば User クラスと 1:1 の関連がある Profile クラスがあるとします。

<?php

namespace App;

class User extends Authenticatable
{

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

上記のように profile メソッドを定義して、関連の存在しない状態で profile メソッドを呼び出すと null が戻ってきて悲しいことになります。そのことを知らずにメソッドチェインすると…。

<?php
// PHP error:  Trying to get property of non-object 😢
\App\User::find(1)->profile->nickname

こういう😢ことが起こります*1。これをどうにか解決できないかなぁと思い、久しぶりにソースを読んでみました。

リレーションがロードされるまでの流れ

Illuminate\Database\Eloquent\Model::__get($key)

最初は存在しないフィールドなので __get($key) が呼ばれます。 getAttribute($key) メソッドが呼ばれるだけ

Illuminate\Database\Eloquent\Model::getAttribute($key)

このメソッドはモデルの属性(カラム)、あるいは Mutator で定義されているものをチェックして存在していればそちらを先に返します。存在しない場合は getRelationValue($key) を呼び出します。

Illuminate\Database\Eloquent\Concerns\HasAttributes::getRelationValue($key)

このメソッドはリレーションが既にロードされている場合はそれを返す。されていない場合は getRelationshipFromMethod($key) を呼び出します。

Illuminate\Database\Eloquent\Concerns\HasAttributes::getRelationshipFromMethod($method)

ここで HasOne リレーションの場合 Illuminate\Database\Eloquent\Relations\HasOne::getResults を経て getDefaultFor を呼び出します。ここがポイントです。 withDefault が定義されてないとそのまま return 。これが null が戻る元凶です。ということは withDefault が定義されていればよい。

<?php
class HasOne extends HasOneOrMany
{
    protected function getDefaultFor(Model $model)
    {
        // ここで return されて null になる
        if (! $this->withDefault) {
            return;
        }

        $instance = $this->related->newInstance()->setAttribute(
            $this->getForeignKeyName(), $model->getAttribute($this->localKey)
        );

        if (is_callable($this->withDefault)) {
            return call_user_func($this->withDefault, $instance) ?: $instance;
        }

        // ここがポイント!!
        if (is_array($this->withDefault)) {
            $instance->forceFill($this->withDefault);
        }

        return $instance;
    }
}

解決策

こうしよう。

<?php
namespace App;

class User extends Authenticatable
{

    public function profile()
    {
        return $this->hasOne(Profile::class)->withDefault();
    }
}

これで空の Profile インスタンスがロードされます。このメソッドは引数に bool or callable で定義されているので、デフォルト値が欲しい場合は…

<?php
namespace App;

class User extends Authenticatable
{

    public function profile()
    {
        return $this->hasOne(Profile::class)->withDefault(function($model) {
            $model->nickname = 'foo';
        });
    }
}

このように実装すると nickname という属性に foo が代入された状態で Profile のインスタンスが戻ります。簡単ですね。これで関連先をロードすると null で困る状態はなくなりました。ちなみに存在チェックをしたい場合は…。

<?php
if (App\User::find(1)->profile->exists) {
    // 存在するときの処理
}

でOKです。

いつもの

最近はサーバーサイドだけでなく、モバイルアプリケーションの作成にも取り掛かろうという動きがあるので iOS/Android アプリケーションエンジニアの方の応募もお待ちしています(切実)。

recruit.innovator.jp.net

*1:HasMany等は空の Collection が戻ります。やさしいせかい

スマホのブラウザでリンクをタップした際にビットコインのウォレットアプリを起動する方法

f:id:akase244:20170512014528j:plain

こんにちは、warikanというビットコインで割り勘ができるツールの開発をしている@akase244です。

ビットコインのウォレットアプリで送金してもらいたい場合、よくある方法としてはQRコードをウォレットアプリのQRコードリーダー機能で読み込んでもらう方法があります。

こうすることで、ウォレットアプリ上でビットコインアドレスと金額がセットされ、あとは送金ボタンを押すだけの状態になります。

今回はwebページ内のリンクをタップした際にQRコードを読み込んだ場合と同様にビットコインのウォレットアプリを起動して、送金ボタンを押すだけの状態にできないかを調査してみました。

続きを読む

PHPでGoogleアナリティクスにトラッキング情報を送りたい

f:id:akase244:20170510094603j:plain

こんにちは、@akase244 です。

会員登録時に認証URLを発行してメール送信を行い、届いたメールに記載されているURLを踏んだ際に会員登録が完了するといった仕組みをみなさんも一度は作ったことがあるんじゃないでしょうか。

この「認証URLにアクセスした」という状態をコンバージョンとしてGoogleアナリティクスに計測させたいというのもよくある要望です。

今回はこのようにサーバー側からGoogleアナリティクスにトラッキング情報を送信する方法を説明します。

続きを読む