express4 で express-flash の利用

# express4でexpress-flashの利用
（npm）express-flash：https://www.npmjs.com/package/express-flash
node.jsのフレームワーク express 4での flash 、express-flash の利用についてのメモ書き程度。

ある日、サンプルのWebページを作ろうかなと思って express と express-flash をインストールして立ち上げてみようと思ったらエラーが・・・。

```
$ node app.js
project/node_modules/express/lib/express.js:112
      throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
・・・
```

え、今までこれで動いてたやん！
npmのexpress-flashのところに書いてあるとおりにしたよ！！
とワタワタしていたら、いつまにか express の(メジャー)バージョンが４に上がっていて、いくつか使えなくなっている関数やらが出てきたようで。。
**教訓： バージョンはしっかり確認しよう！**

さて、そんなわけで、express 4をインストールすると、express-flashのサイトに書いてあるサンプルの通りだと動かないわけで、expreess 4での書き方をメモっておきます。

## まず、必要モジュールのインストール

```
npm install express         # v4.17.1　(2019/12/16現在)
npm install express-flash   # v0.0.2　（２０１９/12/16現在）
npm install express-session # 新たに必要になったもの1
npm install cookie-parser   # 新たに必要になったもの2

# あとはテンプレートエンジン（※ 他のを使う場合は適宜置き換えてください）
npm install ejs
```

## サイト作成
アイテム（名）を追加していくサイト。
同じ名前のアイテムを追加しようとするとエラーを表示するサイトにしました

## app.jsのポイント
* express.cookieParser → cookieParser に
* express.session → session に   
**resave、saveUninitialized、secret** の引数は必須

```app.js
'use strict';
const express = require("express");

// express-flashを使うためのもろもろ
const flash = require('express-flash');
const session = require('express-session');
const cookieParser = require('cookie-parser');

// http処理、POST処理などに利用
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');

const app = express();

// テンプレート、静的ファイルの配置
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// **********************************
// express-flashのサンプルに合わせて

//app.use(express.cookieParser('keyboard cat'));
app.use(cookieParser('keyboard cat'));

//app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: 'rAnd0m',
    cookie: { maxAge: 60000 }}));

app.use(flash());
// **********************************

let g_item_list = [];

// index
app.get('/', async (req, res, next) => {
    res.render('index');
});

// アイテム追加ページ
app.get('/item_add', async (req, res, next) => {
    res.render('item_add');
});

// アイテム追加実行
app.post('/item_add_exec', async (req, res, next) => {
    let item_name = req.body.item_name;
    const find = g_item_list.find((val)=>{
        return (val === item_name);
    });
    if(find !== undefined){
        req.flash('err', 'すでに同じアイテムが登録されています');
        return res.render('item_add');
    }

    // アイテム(名)追加
    g_item_list.push(item_name);

    req.flash('success', 'アイテム登録しました');
    res.redirect('/');
});

const port = (process.env.PORT !== undefined) ? process.env.PORT :3000;
const server = http.createServer(app).listen( port, () => {
    console.log('Server running at http://127.0.0.1:' + port + '/');
});

```

## テンプレートのポイント

成功した(successにセットされた)Flash文言があればこれで表示

```
<% if(messages.success){ %>
  <div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
<% } %>
```

失敗した(errにセットされた)Flash文言があればこれで表示

```
<% if(messages.success){ %>
  <div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
<% } %>
```

```views/index.ejs
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <title>サンプル</title>
</head>
<body>
    <div class="container">
        <h2>サンプル</h2>
        <% if(messages.success){ %>
            <div class="alert alert-success" role="alert"><%=messages.success %></div><br/>
        <% } %>
        <a href="/item_add">アイテム追加</a><br/>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
```

```views/item_add.ejs
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <title>サンプル</title>
</head>
<body>
    <div class="container">
        <h2>アイテム追加</h2>
        <% if(messages.err){ %>
            <div class="alert alert-danger" role="alert"><%=messages.err %></div><br/>
        <% } %>
        <form action='/item_add_exec' method="POST">
            <div class="form-group">
                <label>アイテム名</label><br/>
                <input type="text" name="item_name" />
            </div>
            <div class="form-group">
                <input type="submit" class="btn btn-primary" name="submit" value="登録" />
            </div>
        </form>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

```


## 動作確認
構成はこのようになっているはず

```
node_modules/
views/
  index.ejs
  item_add.js
app.js
package-lock.json
package.json
```

起動

```
node app.js
```

http://127.0.0.1:3000

１） 「アイテム追加」を押下
<img width="300" alt="スクリーンショット 2019-12-16 15.17.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92773/2860066e-eb64-5639-bc9a-4c28598f6164.png">


2) 新規アイテムなら
<img width="300" alt="スクリーンショット 2019-12-16 14.41.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92773/e65e6f61-7b77-6160-54a4-a0ee5125d5ab.png">

3) 同じアイテム名を登録しようとすると
<img width="300" alt="スクリーンショット 2019-12-16 14.42.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92773/d4710429-5828-a3cb-e9c7-1c7d93f55d65.png">

以上です
参考： https://expressjs.com/ja/guide/migrating-4.html