[解決済み] .apply()を使用しようとすると、非オブジェクトでCreateListFromArrayLikeが呼び出されるエラーが発生する。
2022-02-08 09:46:37
質問
私は、コードをきれいに保ち、保守しやすくするために、シンプルで小さなルート解析関数を作成しました。これは、アプリが起動したときに実行される小さな関数で、ルート解析のために
config.json
ファイルを作成し、適切なメソッドとリクエストパスをバインドします。
const fs = require('fs');
const path = require('path');
module.exports = function(app, root) {
fs.readdirSync(root).forEach((file) => {
let dir = path.resolve(root, file);
let stats = fs.lstatSync(dir);
if (stats.isDirectory()) {
let conf = require(dir + '/config.json');
conf.name = file;
conf.directory = dir;
if (conf.routes) route(app, conf);
}
})
}
function route(app, conf) {
let mod = require(conf.directory);
for (let key in conf.routes) {
let prop = conf.routes[key];
let method = key.split(' ')[0];
let path = key.split(' ')[1];
let fn = mod[prop];
if (!fn) throw new Error(conf.name + ': exports.' + prop + ' is not defined');
if (Array.isArray(fn)) {
app[method.toLowerCase()].apply(this, path, fn);
} else {
app[method.toLowerCase()](path, fn);
}
}
}
問題は、Expressルーターに複数の引数を渡す必要がある場合です。例えば、passportを使用する場合は次のようになります。
exports.authSteam = [
passport.authenticate('facebook', { failureRedirect: '/' }),
function(req, res) {
res.redirect("/");
}
];
そこで、配列として渡すことで、ルーターに適切にパースさせることができると考え、例えば以下のような設定を行いました。
{
"name": "Routes for the authentication",
"description": "Handles the authentication",
"routes": {
"GET /auth/facebook": "authFacebook",
"GET /auth/facebook/return": "authFacebookReturn"
}
}
唯一の問題は、このエラーが発生することです。
app[method.toLowerCase()].apply(this, path, fn);
^
TypeError: CreateListFromArrayLike called on non-object
とすれば
console.log(fn)
なるほど
[ [Function: authenticate], [Function] ]
何が間違っているのかよくわからないのですが、何か情報があれば助かります。
解決方法は?
以下のように、パラメータを配列として送信する必要があります。
app[method.toLowerCase()].apply(this, [path, fn]);
引数リストを送信する場合は、callを使用する必要があります。
app[method.toLowerCase()].call(this, path, fn);
関連
-
[解決済み】Facebook Graph API のクエリで with=location を使用すると "Uncaught (in promise) undefined" というエラーが発生する。
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】TypeError:res.jsonは関数ではありません。
-
[解決済み] Node.jsを使うタイミングをどう判断するか?
-
[解決済み] JavaScriptで二重引用符と単一引用符はいつ使うべきですか?
-
[解決済み] varキーワードの目的と、どのような場合に使用する(または省略する)べきですか?
-
[解決済み] encodeURI / encodeURIComponentの代わりにescapeを使用するのはどのような場合ですか?
-
[解決済み] ES6インポートで中括弧を使用するのはどのような場合ですか?
-
[解決済み] ローカルファイルの読み込み時に "Cross origin requests are only supported for HTTP." というエラーが発生する。
-
[解決済み] REST APIからデータを取得しようとしたときに、要求されたリソースに'Access-Control-Allow-Origin'ヘッダーが存在しない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Javascript:getElementById対getElementsById(両方が別のページで動作する)。
-
[解決済み] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングした
-
[解決済み】Google Conversionsが動作しない - スクリプトが読み込まれない
-
[解決済み】コンソールがUnterminated JSX contentsエラーを投げる【終了しました
-
[解決済み】Javascript - ERR_CONTENT_LENGTH_MISMATCH
-
[解決済み】React-Routerの子が1つしかない。
-
[解決済み】ES6マップオブジェクトをソートすることは可能ですか?
-
[解決済み】ETIMEDOUTエラーの対処方法は?
-
[解決済み】未定義のプロパティ 'forEach' を読み取ることができない
-
[解決済み】Javascript、[オブジェクトHTMLInputElement]を表示中。]