Help us understand the problem. What is going on with this article?

Riot.jsでAjaxではなくFetchを使って標準的なやりかたでAPIを取得する

More than 3 years have passed since last update.

Riot.js はカスタムタグを追加していくことで、ひとつのアプリケーションを構築していきます。

たいていのアプリケーションでは外部の RESTful API を呼び出して、そのデータを元に UI を組み立てていきたいと考えるでしょう。

Riot.js のカスタムタグを使って、Facebook のいいね数を取得して表示するというシンプルなカスタムタグを作ってみます。さらに今回は、HTML の新たな標準仕様 Fetch を使って標準的なやりかたで取得します。

TL;DR

<sns-count-facebook> というカスタムタグを定義して、以下のように呼び出すことを前提にします。

<sns-count-facebook url="https://www.google.com"></sns-count-facebook>

カスタムタグの定義はこんな感じになります。

sns-count-facebook.tag
<sns-count-facebook>

    <span>{ count }</span>

    <script>

        this.count = '( Loading... )'

        var self = this

        fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
        .then( function ( data ) {
            return data.json()
        } )
        .then( function ( json ) {
            self.count = json[ 0 ].total_count
            self.update()
        } )

    </script>

</sns-count-facebook>

ES2015 に対応している場合は 後述 のようにシンプルに記述できます。

では詳しく見ていきます。

まずは静的なカスタムタグを定義

分かりやすくするために Facebook の RESTful API を呼び出さない状態から作ってみます。

sns-count-facebook.tag
<sns-count-facebook>

    <span>{ count }</span>

    <script>

        this.count = '( Loading... )'

    </script>

</sns-count-facebook>

表示はこうなります。

( Loading... )

もちろんこのままでは使い物になりません。

Fetch を使って Facebook の RESTful API を呼び出してみます。

RESTful API の呼び出し

Facebook の RESTful API を呼び出す Fetch はこのようなコードになります。

fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + url )
.then( function ( data ) {
    return data.json()
} )
.then( function ( json ) {
    console.log( json )
} )

Ajax は面倒なので jQuery の $.ajax() を使いたくなりますが、今や標準でも十分便利な API ができています。

そもそも Ajax は XMLHttpRequest( XHR )を利用した 手法 の話ですが、Fetch は 低レベルの API です。しかも、何もしなくても Promise を返してくれます。

Riot.js には Fetch や Ajax 関連の API はありませんが、標準でできることは標準でやるのが Riot.js の方針です。

ただし Fetch はまだモバイルブラウザなどが対応していないので、この polyfill を利用すると便利です。

完成

カスタムタグに Fetch を追記すれば完成です。

<sns-count-facebook>

    <span>{ count }</span>

    <script>

        this.count = '( Loading... )'

        var self = this

        fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
        .then( function ( data ) {
            return data.json()
        } )
        .then( function ( json ) {
            self.count = json[ 0 ].total_count
            self.update()
        } )

    </script>

</sns-count-facebook>

count というテンプレート変数にはデフォルトで ( Loading... ) を入れておいて、Facebook からのレスポンスによって書き換えます。

ポイントは、thisself にアサインしていることです。

Riot.js はユーザーのインタラクション( onclick など )に応じたデータストアの更新は自動的に UI に反映してくれますが、Fetch などそれ以外の場合は this.update() を明示的に呼び出す必要があります。1

しかし、Fetch の中では this が Riot.js のタグインスタンスを指さないため、事前に self のようなその他の変数にアサインしておく必要があります。

モダンな環境では

ES2015 が利用できる環境か ES5 へのトランスパイルする場合には、アロー関数によってシンプルに書くことができます。

<sns-count-facebook>

    <span>{ count }</span>

    <script>

        this.count = '( Loading... )'

        fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
        .then( data => data.json() )
        .then( json => {
            this.count = json[ 0 ].total_count
            this.update()
        } )

    </script>

</sns-count-facebook>

カスタムタグの応用

先ほど作った <sns-count-facebook> タグは、単純に Facebook でのいいね数を数字で表示するだけです。

実際には他のカスタムタグから呼び出されることによって、Riot.js の効果を発揮します。

例えば、指定した複数のサイトのいいね数を出す <sns-count> というタグを定義してみます。

sns-count.tag
<sns-count>

    <p each="{ opts.items }">
        { title } の Facebook いいね数は <sns-count-facebook url="{ url }"></sns-count-facebook> です。
    </p>

</sns-count>

この <sns-count> タグを以下のようにマウントすると...

riot.mount( 'sns-count', {
    items : [
        { title : 'Google', url : 'https://www.google.com' },
        { title : 'Facebook', url : 'https://www.facebook.com' },
        { title : 'Twitter', url : 'https://www.twitter.com' }
    ]
} )

このように表示されます。

Google の Facebook いいね数は 3704625 です。
Facebook の Facebook いいね数は 75911262 です。
Twitter の Facebook いいね数は 526350 です。

Facebook のいいね数を取得/表示するという一連のロジックを呼び出す側から隠蔽できました。

ライブデモ

ご自分で試されたいという方は Plunker に ライブデモ を置いたので、いろいろ弄ってみてください。


  1. 公式ドキュメントより > http://riotjs.com/ja/api/#tag-update 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした