Как правильно проверить наличие переменной в шаблоне EJS (используя ExpressJS)? - PullRequest
101 голосов
/ 21 марта 2011

На странице EJS github есть один и только один простой пример: 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)

Я понимаю, что я мог бы устранить эту ошибку, просто добавив локальную переменную "user" в код моего сервера, но суть в том, что я хочу проверить существование таких переменныхво время выполнения, используя каждый день, если / иначе шаблон типа nullcheck.Исключение для переменной, которая не существует, кажется мне смешным.

Ответы [ 10 ]

125 голосов
/ 21 марта 2011

Точно так же, как вы делаете это с чем-либо в js, typeof foo == 'undefined', или так как "locals" - это имя объекта, содержащего их, вы можете сделать if (locals.foo).Это просто сырой js: p

21 голосов
/ 24 марта 2017

Попробуйте добавить в переменную locals

Пример: if(locals.user){}

16 голосов
/ 11 сентября 2017
<% if (locals.user) { %>

 // Your logic goes here 

<% } %>
12 голосов
/ 19 февраля 2014

Чтобы проверить, определен ли пользователь, вам нужно сделать следующее:

<% if (this.user) { %>
   here, user is defined
<% } %>
11 голосов
/ 21 января 2014

Вы можете создать помощника вида, который проверяет «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
5 голосов
/ 18 октября 2013

Я сталкивался с той же проблемой при использовании node.js с mongoose / express / ejs при создании связи между двумя коллекциями вместе с mongoose's populate (), в данном случае admins.user_id существовал, но был связан с несуществующими пользователями. _id.
Итак, не могу найти почему:

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

не удалось выполнить «Не удается прочитать свойство 'name' из null" Затем я заметил, что мне нужно сделать проверку следующим образом:

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

Мне нужно было проверить «контейнер» «name», чтобы оно работало!
После этого это работало так же:

if ( !users.user_id ) ...  

Надеюсь, это поможет.

2 голосов
/ 01 июня 2018

Пришел на эту страницу для ответа, но я придумал более короткий встроенный синтаксис для него:

 <h2><%= user.name ? property.escrow.emailAddress : '' %></h2>
1 голос
/ 19 июля 2016

Для выписки if необходимо использовать typeof:

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

<% } %>
0 голосов
/ 16 января 2018

У меня была такая же проблема, и, к счастью, я обнаружил, что в JS есть также функция короткого замыкания (я знал, что она была в Ruby и некоторых других языках).

На моей стороне сервера / контроллера (это из 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 должен быть без одинарных кавычек, как я видел в предыдущих примерах.Поскольку условие никогда не будет оцениваться как true, так как вы сравниваете строковое значение 'undefined' с типом данных undefined.

0 голосов
/ 13 июля 2016

Я просто передаю объект по умолчанию, который я называю 'data' = '', и передаю его всем моим шаблонам ejs.Если вам нужно передать реальные данные в шаблон ejs, добавьте их как свойство объекта data.

Таким образом, объект data всегда определяется, и вы никогда не получите неопределенное сообщение об ошибке, даже если свойство«данные» существуют в вашем шаблоне ejs, но отсутствуют в вашем экспресс-маршруте узла.

...