Search code examples
expresshandlebars.js

Nested If in Each Statement


I have an application that allows users within a group to look at each member's message to the group and lists them out using {{#each comment}} in my view. I want to limit editing of any comment to only those comments associated with the logged in user using {{#if user.user_id}}.

I tried to nest an if statement within my each section, but it isn't hiding the edit link for those that don't match this case. Is this due to not having an else statement? Could it be that the nested if is from a different object?

Here is my view:

{{#each comment}}
    <div class="col-md-7 col-md-offset-5 comment-card">
        <div class="comment-card-header">
            <p class="card-date">{{this.commentDateSlug}}</p>
            <h3 class="card-title">{{this.title}}</h3>
        </div>
        <div class="comment-card-body">
            <p class="card-report-link">Report: <a href="{{this.commentLink}}" class="card-data-report-url">{{comment.reportLink}}</a></p>
        </div>

        {{#if user.user_id}}
        <p>This is the user: {{user.user_id}}</p>
        <div class="annotation-card-footer">
            <a href="/app/edit/{{this.commentId}}">Edit</a>
        </div>
        {{/if}}
    </div>
{{/each}}

Here is the route:

appRoutes.route('/') 

    .get(function(req, res){

        models.Comment.findAll({
            attributes: ['commentId', 'commentDate', 'dataDateStart', 'dataDateEnd', 'title', 'discovery', 'reportLink'],
            order: 'commentDate DESC',
            include: [{
                model: models.User,
                where: { organizationId: req.user.organizationId },
                attributes: ['organizationId', 'user_id']
            }]
        }).then(function(comment){
            res.render('pages/app/high-level-activity-feed.hbs',{
                comment: comment,
                user: req.user
            });
        })
    })

Solution

  • It sounds like what you want to do in your template is to render the div.annotation-card-footer only for comments whose user_id is equal to the current user's user_id.

    In pseudo-code, this would look something like the following:

    if current_user.user_id equals comment.user_id:
        render div
    

    Handlebars does not have support for comparison operators, so we will need to write our own block helper. There are existing resources about how to do this, see this link, but I will provide an example:

    Handlebars.registerHelper('ifeq', function (value1, value2, options) {
        return ((value1 === value2) ? options.fn(this) : options.inverse(this));
    });
    

    Now that we have registered our helper, we can use it in our template:

    {{#ifeq this.user_id ../user.user_id}}
        <p>This is the user: {{../user.user_id}}</p>
        <div class="annotation-card-footer">
            <a href="/app/edit/{{this.commentId}}">Edit</a>
        </div>
    {{/ifeq}}
    

    One advantage of using a block helper is that we can easily tack on an else branch:

    {{#ifeq this.user_id ../user.user_id}}
        <p>This is the user: {{../user.user_id}}</p>
        <div class="annotation-card-footer">
            <a href="/app/edit/{{this.commentId}}">Edit</a>
        </div>
    {{else}}
        {{! Non-current-user stuff goes here. }}
    {{/ifeq}}