node.js - node - ¿Cuál es la forma correcta de verificar la existencia de una variable en una plantilla EJS(usando ExpressJS)?
express router get params (10)
En la página de EJS github, hay un solo y único ejemplo: https://github.com/visionmedia/ejs
Ejemplo
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
Esto parece verificar la existencia de una variable llamada usuario, y si existe, hacer algunas cosas. Duh, ¿verdad?
Mi pregunta es, ¿por qué en el mundo el nodo arrojaría un ReferenceError si la variable de usuario no existe? Esto hace que el ejemplo anterior sea inútil. ¿Cuál es la forma apropiada de verificar la existencia de una variable? ¿Se espera que use un mecanismo de prueba / captura y tome ese 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)
Entiendo que podría hacer que este error desaparezca simplemente agregando una variable local de "usuario" en mi código de servidor, pero el punto aquí es que quiero verificar la existencia de tales variables en tiempo de ejecución usando su todos los días if / else patrón de tipo nullcheck. Una excepción para una variable que no existe me parece ridícula.
De la misma manera que lo harías con cualquier cosa en js, typeof foo == ''undefined''
, o como "locals" es el nombre del objeto que los contiene, puedes hacer if (locals.foo)
. Es solo js crudo: p
Llegué a esta página para obtener una respuesta, pero se me ocurrió una sintaxis en línea más corta, que es:
<h2><%= user.name ? property.escrow.emailAddress : '''' %></h2>
Lo que hago es simplemente pasar un objeto predeterminado al que llamo ''data'' = '''' y pasarlo a todas mis plantillas ejs. Si necesita pasar datos reales a la plantilla de ejs, agréguelos como propiedad del objeto ''data''.
De esta forma, el objeto ''datos'' siempre se define y nunca aparece un mensaje de error indefinido, incluso si la propiedad de ''datos'' existe en su plantilla ejs pero no en su ruta expresa de nodo.
Me he encontrado con el mismo problema al usar node.js con mongoose / express / ejs al establecer una relación entre 2 colecciones junto con popgo () de mangosta, en este caso existía admins.user_id pero estaba relacionado con un usuario inexistente._id.
Entonces, no pude encontrar por qué:
if ( typeof users.user_id.name == ''undefined'' ) ...
estaba fallando con "No se puede leer la propiedad ''nombre'' de nulo" Luego noté que tenía que hacer la comprobación de esta manera:
if ( typeof users.user_id == ''undefined'' ) ...
Necesitaba verificar el "contenedor" de "nombre", ¡así que funcionó!
Después de eso, esto funcionó de la misma manera:
if ( !users.user_id ) ...
Espero eso ayude.
Para su declaración if
, necesita usar typeof
:
<% if (typeof user == ''object'' && user) { %>
<% } %>
Para verificar si el usuario está definido, debe hacer eso:
<% if (this.user) { %>
here, user is defined
<% } %>
Pruebe anteponer la variable a los locals
Ejemplo: if(locals.user){}
Puede crear un asistente de visualización que compruebe "obj === void 0", este es para 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;
}
Luego úselo en la vista como
<%- get(''deep.nested.non.existent.value'') %> //returns: null
<%- get(''deep.nested.non.existent.value'', "default value") %> //returns: default value
Tuve el mismo problema y, afortunadamente, descubrí que también hay una función de cortocircuito en JS (sabía que había una en Ruby y en otros idiomas).
En mi lado del servidor / controlador (esto es de Node.js / Express):
return res.render(''result'', {survey_result : req.session.survey_result&&req.session.survey_result.survey });
¿Ves lo que hice ahí? El && que sigue después de una variable posiblemente indefinida (es decir, request.session.survey_result
object, que podría o no tener datos de formulario) es la notación de cortocircuito en JS. Lo que hace es solo evaluar la parte que sigue a && si la parte a la izquierda de && NO está indefinida. Tampoco arroja un error cuando la parte izquierda NO está undefined
. Simplemente lo ignora.
Ahora, en mi plantilla (recuerde que pasé el objeto req.session.survey_result_survey
a mi vista como survey_result
) y luego survey_result
campos como:
<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>
Usé el cortocircuito allí también, solo para mantener la seguridad.
Cuando lo probé con las formas sugeridas anteriormente, simplemente:
<% if (typeof survey_result !== undefined) { %>
... <!-- some js and/or html code here -->
<% } %>
A veces, aún intentaría evaluar las propiedades dentro de la declaración IF ... ¿Tal vez alguien puede ofrecer una explicación de por qué?
Además, quería corregir esas necesidades undefined
sin las comillas simples, como vi en los ejemplos anteriores. Porque la condición nunca se evaluará como true
, ya que está comparando un valor de cadena ''undefined''
con un tipo de datos undefined
.
<% if (locals.user) { %>
// Your logic goes here
<% } %>