ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

Monaca + NCMBで日報アプリを作る【その3:日報登録処理を作る】

f:id:mbaasdevrel:20201119154758p:plain

MonacaとNCMBで簡単なアプリを作ってみるハンズオンの資料です。今回は日報アプリを作ってみます。前回の認証に続けて、今回は日報の登録処理を作ります。なおコードはNCMBMania/daily_reportにて公開しています。

日報登録処理を作る

日報登録処理は form.html の #send-report をクリックした際のイベント処理に実装していきます。

// 日報を登録するボタンを押した時の処理です
$('#send-report').on('click', async e => {
  // 情報の取得
  const date = new Date($('#day').val());
  // 日報の保存処理
});

f:id:mbaasdevrel:20201119154836p:plain

新規または既存の日報を検索する

すでに同じ日付の日報があれば、それを更新します。もしなければ新規作成とします。そのための処理として findOrCreate を呼び出します。

// 日報の保存処理
const Report = ncmb.DataStore('Report');
const report = await findOrCreate(date);

findOrCreate は次のようになります。日付と入力者の名前で絞り込みます。

async function findOrCreate(date) {
  // すでに同じ日付の日報があればそれを返す
  const Report = ncmb.DataStore('Report');
  const user = ncmb.User.getCurrentUser();
  const report = await Report
    .equalTo('userName', user.get('userName'))
    .equalTo('day', date)
    .fetch();
  return report.objectId ? report : new Report();
}

新規または既存のrepotオブジェクトができあがったら、必要な変数を準備します。

const acl = new ncmb.Acl();
const user = ncmb.User.getCurrentUser();

ACL(アクセス権限)は次のようにします。これは読み込みは誰でも可能、編集は本人のみという条件です。

acl
  .setPublicReadAccess(true)
  .setUserWriteAccess(user, true);

次に日報に必要な情報を設定します。

report
  .set('day', date)
  .set('report', $('#report').val())
  .set('user', user)
  .set('userName', user.get('userName'))
  .set('acl', acl);

新規作成の場合は save 、更新の場合は update とメソッドが異なるので、分岐します。ついでに処理完了またはエラー時のメッセージも異なるので、分岐します。

const method = report.objectId ? 'update' : 'save';
const message = method === 'update' ? '更新' : '作成';

そして保存します。 try/catchを使います。エラーがあればcatchに移動します。

try {
  await report[method]();
  ons.notification.alert(`日報の${message}に成功しました`);
} catch (e) {
  ons.notification.alert(`日報の${message}に失敗しました`);
}

全体の処理は次のようになります。

$('#send-report').on('click', async e => {
  // 情報の取得
  const date = new Date($('#day').val());
  // 日報の保存処理
  const Report = ncmb.DataStore('Report');
  const report = (await findOrCreate(date)) || new Report();
  const acl = new ncmb.Acl();
  const user = ncmb.User.getCurrentUser();
  acl
    .setPublicReadAccess(true)
    .setUserWriteAccess(user, true);
  report
    .set('day', date)
    .set('report', $('#report').val())
    .set('user', user)
    .set('userName', user.get('userName'))
    .set('acl', acl);
  const method = report.objectId ? 'update' : 'save';
  const message = method === 'update' ? '更新' : '作成';
  try {
    await report[method]();
    ons.notification.alert(`日報の${message}に成功しました`);
  } catch (e) {
    ons.notification.alert(`日報の${message}に失敗しました`);
  }
});

async function findOrCreate(date) {
  // すでに同じ日付の日報があればそれを返す
  const Report = ncmb.DataStore('Report');
  const user = ncmb.User.getCurrentUser();
  const report = await Report
    .equalTo('userName', user.get('userName'))
    .equalTo('day', date)
    .fetch();
  return report.objectId ? report : new Report();
}

日報入力画面表示時の処理

すでに同じ日付の一方があった場合、その入力内容を表示してあげると親切です。これを ons.getScriptPage().onShow で実装します。

ons.getScriptPage().onShow = async function() {
  $('#form-title').html('日報登録フォーム');
  const date = new Date(dayjs().format('YYYY-MM-DD'));
  $('#day').val(dayjs(date).format('YYYY-MM-DD'));
  const report = await findOrCreate(date);
  if (report.objectId) {
    // 日報があれば、その内容を表示
    $('#report').val(report.get('report'))
  }
}

日報を表示する

次に report.html で日報を検索して表示を行います。 この処理は #view-report をクリックした際のイベントで行います。

ons.getScriptPage().onInit = async function() {
  // 日報を閲覧するボタンを押した時の処理
  $('#view-report').on('click', async e => {
    // 検索対象の日付を取得
    const day = new Date($('#date').val());
    // 該当日の日報を取得
    const reports = await fetchReports(day);
    // 取得した日報を表示
    viewReports(reports);
  })
}

f:id:mbaasdevrel:20201119154859p:plain

日報を取得する

日報を取得する処理は fetchReports になります。これは指定された日付を条件に検索を実行するだけです。

// 日報の取得
async function fetchReports(day) {
  const Report = ncmb.DataStore('Report');
  return await Report
    .equalTo('day', day)
    .include('user')
    .fetchAll();
}

後は viewReports で結果をHTML表示するだけです。

// 日報の表示処理
function viewReports(reports) {
  const html = [];
  html.push(`<ons-list-header>${dayjs(day).format('YYYY年MM月DD日の日報')}</ons-list-header>`)
  reports.forEach(report => {
    html.push(`
      <ons-list-item expandable>
        ${report.get('user').displayName}
        <div class="expandable-content">
          ${report.get('report').replace(/\n/g, '<br />')}
        </div>
      </ons-list-item>
    `)
  });
  $('#reports').html(html.join(''));
}

まとめ

ここまでの処理で認証、日報の登録と閲覧ができるようになりました。利用したmBaaSの機能は次の通りです。

  • 会員登録(ID/パスワード)
  • 会員認証(ID/パスワード)
  • データストア登録/更新
  • データストア検索

mBaaSには他にもたくさんの機能があります。ぜひほかのハンズオンで体験してください。

「Monacaで日報アプリ」記事一覧はこちら

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。