今回は楽天レシピAPIを使ってレシピ情報を見るアプリを作ってみたいと思います。
作成するアプリについて
今回作成するアプリは、まず最初にレシピのカテゴリが一覧表示されます。
カテゴリをタップするとレシピが並びます。
レシピをタップすると、そのレシピの簡単な情報が表示されます。
さらに詳細なレシピ情報はInAppBrowserにて楽天レシピのサイトにアクセスして表示されます。
以上の4つの画面で構成されたアプリになります。
楽天レシピAPIについて
今回利用するWeb APIは以下の2つです。
利用の際にはアプリIDが必要になりますので新規アプリ登録より登録してください(楽天のユーザIDが必要です)。
プロジェクトの作成
今回のアプリは「Onsen UI V2 JS Navigation」テンプレートを使用して作成しています。一覧/詳細画面があるようなアプリではこのテンプレートをベースにすると良いでしょう。
また、[JS/CSSコンポーネントの追加と削除]メニューより、jQueryを追加してください。
HTMLの実装について
HTMLはInAppBrowserの画面を除く、全部で3つの画面で構成されます。
カテゴリ一覧画面
この画面では楽天レシピカテゴリ一覧APIからデータを取得し、#categories
の中にデータを追加します。
<ons-navigator id="navigator" page="page1.html"></ons-navigator>
<ons-template id="page1.html">
<ons-page id="first-page">
<ons-toolbar>
<div class="center">カテゴリ</div>
</ons-toolbar>
<div class="content" style="text-align: center">
<p id="loading">
<ons-progress-circular indeterminate></ons-progress-circular>
</p>
<ons-list id="categories">
</ons-list>
</div>
</ons-page>
</ons-template>
レシピ一覧
この画面では前の画面で選択されたカテゴリに基づいて楽天レシピカテゴリ別ランキングAPIの結果を取得し、 #recipes
の中にレシピ情報を追加します。また、#categoryName
に選択されたカテゴリ名を表示します。
<ons-template id="page2.html">
<ons-page id="second-page">
<ons-toolbar>
<div class="left"><ons-back-button>一覧</ons-back-button></div>
<div class="center" id="categoryName">カテゴリ名</div>
</ons-toolbar>
<div class="content" style="text-align: center">
<ons-list id="recipes">
</ons-list>
</div>
</ons-page>
</ons-template>
レシピ情報表示
この画面では前の画面で選択されたレシピの情報を表示します。この時点では詳細なレシピ情報は得られませんので代表的な情報を #detail
の中に表示します。
<ons-template id="page3.html">
<ons-page id="third-page">
<ons-toolbar>
<div class="left"><ons-back-button>レシピ</ons-back-button></div>
<div class="center" id="recipeTitle">Page 2</div>
</ons-toolbar>
<div class="content" style="text-align: center">
<img src="" id="recipeImage" style="width:100%" />
<div id="detail">
<ons-list>
</ons-list>
</div>
</div>
</ons-page>
</ons-template>
JavaScriptについて
JavaScriptは主に3つのブロックに分かれます。
- カテゴリ一覧画面
- レシピ一覧画面
- レシピ詳細画面
まず全体の処理は次のようになります。
// 楽天APIのアプリID
var RAKUTEN_APP_ID = "RAKUTEN_APP_ID";
// ページが切り替わる度に呼ばれます
document.addEventListener('init', function(event) {
var page = event.target;
// カテゴリ一覧画面の場合
if (page.matches('#first-page')) {
// レシピ一覧画面の場合
} else if (page.matches('#second-page')) {
// レシピ詳細画面の場合
} else if (page.matches('#third-page')) {
}
});
カテゴリ一覧画面
カテゴリ一覧画面では次の処理を行います。
- 楽天レシピカテゴリ一覧APIを呼んで結果に基づいてカテゴリ一覧を表示
- カテゴリをタップしたら、そのカテゴリの楽天レシピカテゴリ別ランキングAPIを呼ぶ
- レシピ一覧画面へ遷移
楽天レシピカテゴリ一覧APIを呼んで結果に基づいてカテゴリ一覧を表示
一覧表示を行う際にはカテゴリ一覧取得APIのURLを指定し、JSONPでコールします。JSONPにすることによってMonaca IDE上でも動作が確認できるようになります。
そして結果が返ってきたら、カテゴリの配列(data.result.large)を順番に <ons-list-item />
の中に追加しています。data-id
属性にカテゴリIDを指定しておきます。これはカテゴリをタップした際に使います。
// カテゴリ一覧取得APIの設定
let url = `https://app.rakuten.co.jp/services/api/Recipe/CategoryList/20121121?applicationId=${RAKUTEN_APP_ID}&categoryType=large`;
// Ajaxで取得
$.ajax({
url: url,
dataType: 'jsonp'
})
.then(function(data) {
// 取得できたらOnsen UIのタグを生成します
let ary = [];
let categories = data.result.large;
for (let i = 0; i < categories.length; i++) {
let category = categories[i];
ary.push(`<ons-list-item class="category" data-id="${category.categoryId}" modifier="chevron" tappable>${category.categoryName}</ons-list-item>`);
}
// できあがったHTMLを表示します
$("#categories").html(ary.join(""));
});
カテゴリをタップしたら、そのカテゴリの楽天レシピカテゴリ別ランキングAPIを呼ぶ
カテゴリは動的に生成しますので次のようにjQueryでタップイベントをキャッチします。data-id
を取得し、それを使ってレシピを取得するURLを作成します。
// カテゴリをタップした際のイベントを設定します
$(page).on("click", ".category", function(e) {
// data-idで指定したカテゴリのIDを取得します
let category_id = $(e.target).parent('ons-list-item').data("id");
// カテゴリ名を取得します
let categoryName = $(e.target).text();
// レシピを取得するAPIのURLを設定します
let url = `https://app.rakuten.co.jp/services/api/Recipe/CategoryRanking/20121121?applicationId=${RAKUTEN_APP_ID}&categoryId=${category_id}`;
// Ajaxを実行します
$.ajax({
url: url,
dataType: 'jsonp'
})
.then(function(data) {
// 取得成功時の処理(後述)
});
});
取得成功時の処理:レシピ一覧画面へ遷移
楽天レシピカテゴリ別ランキングAPIの実行が成功したら、取得したデータを次の画面に引き継ぎます。data
オプションを使って次の画面にデータを渡すことができます。
// 取得できたら次のページに遷移します
// 取得したデータをdataオプションとして引き継ぎます
document.querySelector('#navigator').pushPage('page2.html', {
data: {
recipes: data.result,
title: categoryName
}
});
レシピ一覧画面
この画面では前の画面から渡された情報を元にレシピ一覧を表示します。この画面では次のような処理を行います。
- レシピ一覧を表示
- レシピをタップした際にレシピ詳細画面へ遷移
レシピ一覧を表示
レシピ一覧を表示する際には前画面から渡された情報を <ons-list-item />
の中に表示します。左側にサムネイル画像を、その横にレシピのタイトルを表示します。
前の画面ではカテゴリIDを data-id
に紐付けていましたが、今回は配列のインデックスを data-recepe-index
に紐づけます。これはタップしたレシピの情報を取得しやすくするためです。
// 前画面から送られているデータを取得
let data = event.target.data;
// カテゴリ名を表示
$("#categoryName").text(data.title);
// レシピ一覧のHTMLを生成
let ary = [];
let recipes = data.recipes;
for (let i = 0; i < recipes.length; i++) {
let recipe = recipes[i];
ary.push(`<ons-list-item class="recipe" data-recepe-index="${i}" modifier="chevron" tappable>
<div class="left">
<img class="list-item__thumbnail" src="${recipe.foodImageUrl}">
</div>
<div class="center">
${recipe.recipeTitle}
</div>
</ons-list-item>`);
}
// レシピ一覧を表示
$("#recipes").html(ary.join(""));
レシピをタップした際にレシピ詳細画面へ遷移
表示されたレシピをタップしたら呼ばれるイベントです。ここではタップされたレシピを特定し、その情報を次の画面に渡します。
// レシピをタップした際のイベント
$(page).on("click", ".recipe", function(e) {
// 上から何番目をタップしたかを取得
let index = $(e.target).parent('ons-list-item').data('recepe-index');
// 次の画面へレシピ情報を引き渡し
document.querySelector('#navigator').pushPage('page3.html', {
data: {
recipe: recipes[index]
}
});
});
レシピ情報表示
レシピの情報を表示する画面です。ここでは前画面から渡されたレシピ情報を表示します。
// レシピ情報を表示
let recipe = event.target.data.recipe;
$("#recipeTitle").text(recipe.recipeTitle);
$("#recipeImage").attr("src", recipe.foodImageUrl);
$("#detail").html(`
<ons-list-item>
<div class="right">
${recipe.nickname}さん
</div>
</ons-list-item>
<ons-list-item>
<div style="text-align:left">
${recipe.recipeDescription}
</div>
</ons-list-item>
<ons-list-header>材料</ons-list-header>
<ons-list-item>
<div style="text-align:left">
${recipe.recipeMaterial.join(", ")}
</div>
</ons-list-item>
<ons-list-item>
<ons-button modifier="large" class="open">
レシピを見る
</ons-button>
</ons-list-item>
`);
最後にレシピを見るボタンをタップした際の処理を作ります。レシピの元URLを、InAppBrowserで表示します。
// レシピの詳細をInAppBrowserで表示します
$(page).on("click", ".open", function(e) {
var ref = window.open(recipe.recipeUrl, '_blank', 'location=no&toolbar=no');
});
ここまでのコードでカテゴリの表示、レシピ一覧と詳細、そしてInAppBrowserによるレシピ表示までが行えるようになりました。
今回のコードはmoongift/monaca-rakuten-recipe-apiにアップロードされています。実装時の参考にしてください。