[Handlebars] Register Helper - Where to define Handlebars?
Closed this issue ยท 12 comments
I am attempting to use Handlebars register helper to display edit and delete buttons if the data belongs to the current user. Currently, my handlebars is showing the buttons for every comment.
I am struggling with where to places the Handlebars register helper function and exactly how to define Handlebars. I have tried placing the following code in both the index.js file so it loads on document ready and then in the comments events.js file. I get pretty much the same error message in both cases.
It looks like I am pointing it to the wrong file.
js file:
const Handlebars = require('handlebars');
Handlebars.registerHelper('checkUser', function(comment){
return comment.user_id === app.user_id;
});
handlebars template:
{{#each comments}}
<div class="comment-module">
<div class="text-align-left">
<h4>{{trip.name}}</h4>
<div class="comment" data-id={{id}}>
<p class"add-padding">{{user.email}} says:</p>
<p>"{{comments}}"</p>
</div>
</div>
{{#if checkUser}}
<button type="click" class:"block" id="delete-comment" data-id={{id}}>X</button>
<button type="click" class:"block" id="get-single-comment" data-id={{id}}>edit</button>
{{/if}}
</div>
{{/each}}
@berziii can you help out with this? I meant to ask you about it. Jen is trying to find out where to put her handlebars helper.
Woops. Meant @berziiii. Sorry @berziii
@gaand, here is my code that invokes the handlebars template. It seems like this code would need to be placed in a new file altogether?
assets/scripts/comments/events.js
const getFormFields = require('../../../lib/get-form-fields');
const api = require('./api');
const ui = require('./ui');
const onGetComments = function (event) {
event.preventDefault();
api.getComments(event)
.done (ui.getCommentsSuccess)
.fail (ui.failure);
};
const addHandlers = () => {
$('#my-comments').on('click', onGetComments);
};
assets/scripts/comments/ui.js
const app = require ('../app');
const loadComments = require ('../../templates/comments.handlebars');
const loadSingleComment = require ('../../templates/edit-comment.handlebars');
const getCommentsSuccess = (data) => {
let allComments = data;
$('.container').html(loadComments(allComments));
$('.single-trip-page').hide();
$('.edit-comment-page').hide();
};
After looking around, this may be a bit more work than you want to tackle (it probably involves changing how webpack loads things).
Luckily, there's another way to make this work. If you look at the example serializer in the rail-api-template, it shows how you can include an ownership boolean in the JSON response. Then your template can just check that boolean.
Please have a look.
Jen, your other option would just be to show an error to the user when they click that button and you get a 422 back. This kind of thing get a whole lot easier with ember!!
Not showing the buttons for an action that cannot be taken is a much better option.
That said, handling errors is always a good idea.
@jenboyd Have you had a chance to look at the example serializer?
I found the code below in the example serializer. I'm thinking I can probably add this to my comments serializer, as well. I would then update my handlebars template to say if editable then display button. I will try it out!
class ExampleSerializer < ActiveModel::Serializer
attributes :id, :text, :editable
def editable
scope == object.user
end
end
@payne-chris-r @gaand, I added the the editable method to the comments serializer and adjusted the handlebars. Everything is working as expected. Users can no longer see the buttons to edit or delete other users comments. Thanks for your help!
My working code below:
comments serializer
class CommentSerializer < ActiveModel::Serializer
attributes :id, :comments, :editable
has_one :user
has_one :trip
def editable
scope == object.user
end
end
comments.handlebars
{{#each comments}}
<div class="comment-module">
<div class="text-align-left">
<h4>{{trip.name}}</h4>
<div class="comment" data-id={{id}}>
<p class"add-padding">{{user.email}} says:</p>
<p>"{{comments}}"</p>
</div>
</div>
{{#if editable}}
<button type="click" class:"block" id="delete-comment" data-id={{id}}>X</button>
<button type="click" class:"block" id="get-single-comment" data-id={{id}}>edit</button>
{{/if}}
</div>
{{/each}}