web-dev-qa-db-ja.com

EJSテンプレート内の変数の存在を確認する適切な方法は何ですか(ExpressJSを使用)?

EJSのgithubページには、単純な例が1つだけあります。 https://github.com/visionmedia/ejs

<% if (user) { %>
    <h2><%= user.name %></h2>
<% } %>

これは、userという名前の変数の存在を確認しているようです。存在する場合は、何らかの処理を行います。ねえ?

私の質問は、ユーザー変数が存在しない場合、なぜ世界でNode ReferenceErrorをスローするのでしょうか?これにより、上記の例は役に立たなくなります。変数の存在を確認する適切な方法は何ですか? ?try/catchメカニズムを使用してReferenceErrorを取得する予定ですか?

ReferenceError: user is not defined
    at IncomingMessage.anonymous (eval at <anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:140:12))
    at IncomingMessage.<anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:142:15)
    at Object.render (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:177:13)
    at ServerResponse.render (/usr/local/lib/node/.npm/express/1.0.7/package/lib/express/view.js:334:22)
    at Object.<anonymous> (/Users/me/Dropbox/Projects/myproject/server.js:188:9)
    at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)
    at pass (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:162:10)
    at /usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:152:27
    at Object.restrict (/Users/me/Dropbox/Projects/myproject/server.js:94:5)
    at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)

私はサーバーコードに「ユーザー」ローカル変数を追加するだけでこのエラーを解消できることを理解していますが、ここでの全体的なポイントは、毎日のif/elseを使用して実行時にそのような変数の存在を確認したいということですnullcheck型パターン。存在しない変数の例外はばかげているようです。

103
Aashay Desai

Js、_typeof foo == 'undefined'_、または「locals」がそれらを含むオブジェクトの名前なので、if (locals.foo)を実行できます。それは生のjsです:p

128
tjholowaychuk

localsを変数の先頭に追加してみてください

例:if(locals.user){}

21
spencer.sm
<% if (locals.user) { %>

 // Your logic goes here 

<% } %>
16
Anirudh

ユーザーが定義されているかどうかを確認するには、それを行う必要があります。

<% if (this.user) { %>
   here, user is defined
<% } %>
12
HenioJR

「obj === void 0」をチェックするビューヘルパーを作成できます。これはexpress.js用です。

res.locals.get = function() {
    var args = Array.prototype.slice.call(arguments, 0);
    var path = args[0].split('.');
    var root = this;
    for (var i = 0; i < path.length; i++) {
        if(root[path[i]] === void 0) {
            return args[1]?args[1]:null;
        } else {
            root = root[path[i]];
        }
    };
    return root;
}

次に、ビューでそれを使用します

<%- get('deep.nested.non.existent.value') %>  //returns: null
<%- get('deep.nested.non.existent.value', "default value") %> //returns: default value
11
Paulius Uza

Node.jsとmongoose/express/ejsを使用して、mongooseのpopulate()と2つのコレクションをリレーションするときに同じ問題に遭遇しました。この場合、admins.user_idは存在しましたが、存在しないusers._idに関連していました。
したがって、理由が見つかりませんでした。

if ( typeof users.user_id.name == 'undefined' ) ...

「nullのプロパティ 'name'を読み取れません」で失敗していました。その後、次のようなチェックを行う必要があることに気付きました。

if ( typeof users.user_id == 'undefined' ) ...

「名前」の「コンテナ」を確認する必要があったので、うまくいきました!
その後、これは同じように機能しました。

if ( !users.user_id ) ...  

それが役に立てば幸い。

5
aesede

答えのためにこのページに来ましたが、私はそれのために短いインライン構文を思い付きました:

 <h2><%= user.name ? property.escrow.emailAddress : '' %></h2>
2
Adam Boostani

ifステートメントには、typeofを使用する必要があります。

<% if (typeof user == 'object' && user) { %>

<% } %>
1
Fabien Thetis

私がしているのは、 'data' = ''と呼ぶデフォルトのオブジェクトを渡して、それをすべてのejsテンプレートに渡すだけです。実際のデータをejsテンプレートに渡す必要がある場合は、それらを 'data'オブジェクトのプロパティとして追加します。

このように、「data」オブジェクトは常に定義され、「data」のプロパティがejsテンプレートに存在するがノードエクスプレスルートには存在しない場合でも、未定義のエラーメッセージが表示されることはありません。

0
Robert Brax

私は同じ問題を抱えていましたが、幸いなことに、JSには短絡関数もあることがわかりました(Rubyおよびその他の言語に1つあることを知っていました)。

私のサーバー/コントローラー側(これはNode.js/Expressから):

return res.render('result', {survey_result : req.session.survey_result&&req.session.survey_result.survey }); 

私がそこで何をしたかを見てください?未定義の可能性のある変数の後に続く&&(つまり、フォームデータがある場合とない場合があるrequest.session.survey_resultオブジェクト)は、JSの短絡表記です。 &&の左側の部分が未定義でない場合、&&に続く部分のみを評価します。また、左側の部分IS undefined。の場合はエラーをスローしません。単に無視します。

次に、テンプレートで(オブジェクトreq.session.survey_result_surveyオブジェクトをsurvey_resultとしてビューに渡したことを思い出してください)、フィールドを次のようにレンダリングしました:

<table>
    <tr>
        <td> Name:</td>
        <td> <%=survey_result&&survey_result.name%></td>
    </tr>
    <tr>
        <td> Dojo Location:</td>
        <td> <%=survey_result&&survey_result.dojo_loc%></td>
    </tr>
    <tr>
        <td> Favourite Language:</td>
        <td> <%=survey_result&&survey_result.fave_lang%></td>
    </tr>

安全のために、ここでも短絡回路を使用しました。

以前に提案された方法でそれを試したとき、ちょうど:

<% if (typeof survey_result !== undefined) { %>
... <!-- some js and/or html code here -->
<% } %>

場合によっては、IFステートメント内のプロパティを評価しようとすることもあります...誰かが理由を説明できるでしょうか?

また、前の例で見たように、undefinedは単一引用符なしである必要があることを修正したかったのです。文字列値'undefined'をデータ型trueと比較しているため、条件はundefinedに評価されないためです。