web-dev-qa-db-fra.com

Quel est le moyen approprié de vérifier l'existence d'une variable dans un modèle EJS (à l'aide d'ExpressJS)?

Sur la page github d'EJS, il n'y a qu'un seul exemple simple: https://github.com/visionmedia/ejs

Exemple

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

Cela semble vérifier l'existence d'une variable nommée utilisateur et, si elle existe, effectuer des tâches. Duh, c'est ça?

Ma question est la suivante: pourquoi dans le monde Node émettrait une erreur ReferenceError si la variable utilisateur n'existe pas? Ceci rend l'exemple ci-dessus inutile. Quel est le moyen approprié de vérifier l'existence d'une variable ? Suis-je censé utiliser un mécanisme try/catch et récupérer ce 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)

Je comprends que je pourrais faire disparaître cette erreur en ajoutant simplement une variable locale "utilisateur" dans le code de mon serveur, mais l’essentiel ici est que je veuille vérifier l’existence de telles variables au moment de l’exécution en utilisant votre tous les jours si/sinon modèle de type nullcheck. Une exception pour une variable qui n'existe pas me semble ridicule.

103
Aashay Desai

De la même manière que vous le feriez avec n'importe quoi dans js, typeof foo == 'undefined', Ou puisque "locals" est le nom de l'objet qui les contient, vous pouvez faire if (locals.foo). C'est juste brut js: p

128
tjholowaychuk

Essayez de préfixer la variable avec locals

Exemple: if(locals.user){}

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

 // Your logic goes here 

<% } %>
16
Anirudh

Pour vérifier si l'utilisateur est défini, vous devez le faire:

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

Vous pouvez créer un assistant de vue qui recherche "obj === void 0", celui-ci concerne 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;
}

Puis utilisez-le dans la vue comme

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

J'ai rencontré le même problème en utilisant node.js avec mongoose/express/ejs lors de l'établissement d'une relation entre 2 collections avec populate () de mongoose, dans ce cas admins.user_id existait mais était lié à un utilisateur inexistant.
Alors, je ne trouvais pas pourquoi:

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

échouait avec "Impossible de lire la propriété 'nom' de null" Ensuite, j'ai remarqué que je devais faire la vérification comme ceci:

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

J'avais besoin de vérifier le "conteneur" de 'name', donc ça a fonctionné!
Après cela, cela a fonctionné de la même manière:

if ( !users.user_id ) ...  

J'espère que ça aide.

5
aesede

Arrivé à cette page pour une réponse, mais je suis venu avec une syntaxe en ligne plus courte pour elle qui est:

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

Pour votre instruction if, vous devez utiliser typeof:

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

<% } %>
1
Fabien Thetis

Ce que je fais est simplement de passer un objet par défaut que j’appelle 'data' = '' et de le transmettre à tous mes modèles ejs. Si vous devez transmettre des données réelles au modèle ejs, ajoutez-les en tant que propriété de l'objet 'data'.

De cette façon, l'objet 'data' est toujours défini et vous n'obtenez jamais de message d'erreur non défini, même si la propriété 'data' existe dans votre modèle ejs mais pas dans la route express de votre nœud.

0
Robert Brax

J'ai eu le même problème, et heureusement, j'ai trouvé qu'il y avait aussi une fonction de court-circuit dans JS (je savais qu'il en existait une dans Ruby et quelques autres langues).

Sur le côté serveur/contrôleur (à partir de Node.js/Express):

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

Regarde ce que j'ai fait là? Le && qui suit une variable éventuellement non définie (c.-à-d. request.session.survey_result objet, avec ou sans données de formulaire) est la notation de court-circuit dans JS. Ce qu'il fait, c'est évaluer seulement la partie qui suit le && si la partie à gauche du && n'est PAS indéfinie. Il ne génère pas non plus d'erreur lorsque la partie gauche IS undefined. Il l'ignore simplement.

Maintenant, dans mon modèle (rappelez-vous que j’ai passé l’objet req.session.survey_result_survey objecte à ma vue comme survey_result) puis j'ai rendu les champs comme suit:

<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>

J'ai aussi utilisé le court-circuit, juste pour des coffres-forts.

Lorsque j'ai essayé avec les méthodes précédemment suggérées, il suffit de:

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

Parfois, il essayait toujours d’évaluer les propriétés dans la déclaration SI ... Peut-être que quelqu'un pourrait expliquer pourquoi?

De plus, je voulais corriger le fait que undefined doit se passer de guillemets simples, comme je l’ai vu dans les exemples précédents. Parce que la condition ne sera jamais évaluée à true, car vous comparez une valeur de chaîne 'undefined' avec un type de données undefined.