Express Handlebars getting first letter of every string - javascript

Some discord servers don't have icons, and discord renders the icons as the first char of each word in the guilds name. I am trying to do that in handlebars with express. I did the following, but it errored.
<h1>Welcome, {{username}}!</h1>
<ul>
<h2>Your guilds</h2>
{{#each guilds as |key value|}}
<li>
{{#if key.icon}}
<img src="https://cdn.discordapp.com/icons/{{key.id}}/{{key.icon}}?size=64" alt="profile"> </p>{{key.name}}</p>
{{else}}
<div>
<h3>{{ key.name.match(/\b\w/g).join('') }}</h3>
<p>{{key.name}}</p>
</div>
{{/if}}
</li>
{{/each}}
</ul>
Error
Error: Parse error on line 10:
... <h3>{{ key.name.match(/\b\w/g).join(
-----------------------^
Expecting 'ID', got 'INVALID'

In Handlebars, you can work with custom helpers functions that handle javascript logic outside the templates. You should make two changes in your project to achieve that:
create a file with custom helpers, normally inside helpers folder in your project:
./helpers/hbs.js
function getFirstLetter(name) {
return name.match(/\b\w/g).join("");
}
module.exports = { getFirstLetter };
Modify handlebars middleware configuration in the app.js to use custom helpers created by you:
./app.js
/**
* Import Handlebars
*/
const exphbs = require("express-handlebars");
/**
* Import Custom Helpers
*/
const hbs = require("./helpers/hbs");
/**
* Template Engine
*/
app.engine(
".hbs",
exphbs({
... all configuration here...
helpers: hbs, // add custom helpers.
})
);
Now you can use custom helper inside your template like this:
<h1>Welcome, {{username}}!</h1>
<ul>
<h2>Your guilds</h2>
{{#each guilds as |key value|}}
<li>
{{#if key.icon}}
<img src="https://cdn.discordapp.com/icons/{{key.id}}/{{key.icon}}?size=64" alt="profile"> </p>{{key.name}}</p>
{{else}}
<div>
<h3>{{getFirstLetter key.name}}</h3>
<p>{{key.name}}</p>
</div>
{{/if}}
</li>
{{/each}}
</ul>

Related

[Vue Warn]: Property "toggleFavorites" was accessed during render but is not defined on instance error

I was creating some web app with vuejs2 CLI options API and I tried to create an event emitter but it keeps saying it has an error in the console and doesn't show up anything when the button which has the event emitter is clicked.
The error is shown in the console
And this was my code in the child component:
<template>
<li>
<h2>{{ name }} {{ friendIsFavorite ? "(Favorite)" : "" }}</h2>
<button #click="toggleFavs">Toggle Favorite</button>
<button #click="toggleDetails">Show Details</button>
<ul v-if="detailsAreVisible">
<li><strong>Phone:</strong> {{ phoneNumber }}</li>
<li><strong>Email:</strong> {{ emailAddress }}</li>
</ul>
</li>
</template>
The first button with the toggleFavs method is the one I sent an event emitter with this method
toggleFavs() {
this.$emit("toggle-fav", this.id);
},
The code on the main App.vue component is this:
<template>
<header> <h1>My Friends</h1></header>
<ul>
<friend-contact
v-for="friend in friends"
:key="friend.id"
:id="friend.id"
:name="friend.name"
:phone-number="friend.phone"
:email-address="friend.email"
:is-favorite="friend.isFavorite"
#toggle-fav="toggleFavorites"
></friend-contact>
</ul>
</template>
where the method of the event is defined as:
toggleFavorites() {
// const targetedFriend = this.friends.find(
// (friend) => friend.id === friendId
// );
// console.log(targetedFriend);
// targetedFriend.isFavorite = !targetedFriend.isFavorite;
alert("This Works"); //just for demonstration but not working
help me out guys I'm stuck.
here is the code:
There were two problems with your code. The first was mentioned by #BoussadjraBrahim and it was a typo (mehtod instead of methods). The second problem was not importing your FriendContact component in the App.vue and adding it to the components object.
<script>
import FriendContact from './FriendContact.vue'
export default {
components: {
FriendContact
},
...
methods: {
...
</script>
Fixed example code

Vue and firebase database

<template lang="html">
<div class="">
<ul>
<li>{{ this.anArray.model }}</li>
</ul>
</div>
</template>
<script>
import db from '../firebase/init.js';
var link = db.ref('cars').child('-KoKST99e110OZs6g111');
var thedata = link.once('value').then(function(snapshot){return snapshot.val()});
export default {
name: 'view',
firebase: {
anArray:thedata
}
}
</script>
I trying to get the object inside that path on firebase database but is answer unknown. the connection is good, the problem is how Im doing it. Help!

Ember use separate child template files

I have the below template file (actually used for my component)
{{#each details.secs as |sec|}}
<div class="row">
{{#each secs.flds as |fld|}}
// if fld.id is 'abc', use abc.hbs
// if fld.id is 'xyz', use xyz.hbs
{{/each}}
</div>
{{/each}}
My question is how can I use separate sub-template files and include them in the above parent file (based on condition)
Thus if field.id is 'abc', it should use rendering logic from abc.hbs
Also abc.hbs would need the 'field' model input for rendering purpose (It's output should get appended to the main template)
With Ember 2.0, creating and registering our own eq (equals) helper is super easy:
ember generate helper eq
Include our equality function:
// app/helpers/eq.js
import Ember from 'ember';
export function eq(params, hash) {
return (params[0] === params[1]);
}
export default Ember.Helper.helper(eq);
And use it!
{{#each details.sections as |section|}}
<div class="row">
{{#each section.fields as |field|}}
{{#if (eq field.id "abc")}}
{{abc-component data=field}}
{{/if}}
 {{#if eq field.id "xyz)}}
{{xyz-component data=field}}
{{/if}}
{{/each}}
</div>
{{/each}}

Ember CLI- conditional output within an each loop using a component instead of itemController

In my Ember CLI app, I'm using {{#each}} helpers to output the rows of a table. 'name' 'created_date' and 'type' are all defined in the related model.
{{#each model as |job|}}
<tr>
<td>{{job.name}}</td>
<td>{{job.created_date}}</td>
<td>{{job.type}}</td>
<td>
{{#if typeZero}}
<p>Content that will display if the value of 'type' is 0.</p>
{{/if}}
</td>
</tr>
{{/each}}
In the fourth table cell of each row, I'd like to display certain content if that value of 'type' for that record is 0.
I first tried adding an itemController to the each helper:
{{#each job in model itemController="jobrowcontroller"}}
......
{{/each}}
This gave me an error: "Uncaught Error: Assertion Failed: The value that #each loops over must be an Array. You passed ***#controller:array:, but it should have been an ArrayController"
I found that itemController is now deprecated, and components should be used instead.
I created a component named job-table-row, and updated the page template:
{{#each model as |job|}}
{{#job-table-row model=job as |jobTableRow|}}
<tr>
<td>{{job.name}}</td>
<td>{{job.created_date}}</td>
<td>{{job.type}}</td>
<td>
{{#if typeZero}}
<p>Content that will display if the value of 'type' is 0.</p>
{{/if}}
</td>
</tr>
{{/job-table-row}}
{{/each}}
In the component handlebars file, I simply use {{yield}} and everything displays fine.
In the component js file, I have:
import Ember from 'ember';
export default Ember.Component.extend({
tagName: '',
typeZero: function() {
var currentStatus = this.get('model.status');
if (currentStatus === 0) {
this.set('typeZero', true);
} else this.set('typeZero', false);
}.on('didInsertElement'),
});
The problem with this is that the function 'typeZero' doesn't run. Is it possible to achieve this with a component, or do I need to use a different method altogether?
You cannot yield because typeZero only exists inside the component. Instead, move the template to the component:
// templates/components/job-table-row.hbs
<td>{{model.name}}</td>
<td>{{model.created_date}}</td>
<td>{{model.type}}</td>
<td>
{{#if statusZero}}
<p>Content that will display if the value of 'status' is 0.</p>
{{/if}}
</td>
And simplify your template outside:
<table>
<tbody>
{{#each model as |job|}}
{{job-table-row model=job}}
{{/each}}
</tbody>
</table>
Also, you can replace your complex method with a computed property:
// components/job-table-row.js
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'tr',
statusZero: Ember.computed.equal('model.status', 0)
});
See it all working at http://ember-twiddle.com/de8a41b497ef4f116bab

How render a route relevant subheader with meteor blaze?

The end result of all of what I am about to go over is the subheader is not rendering on screen like i want it to.
Currently there is a mongo collection subheader with a category field and a texth field.
Subheader = new Mongo.Collection('subheader');
Meteor.methods({
subheaderInsert: function(subheaderIdAttributes) {
check(String);
check(subheaderIdAttributes, {
texth: String,
category: String
});
var subheaderId = _.extend(postAttributes, {
submitted: new Date()
});
var subheaderId = SubheaderId.insert(subheader);
return {
_id: subheaderId
};
}
});
There is a route that subscribes to the subheader and other page data.
Router.route('/', {
name: 'home',
controller: MissionstatementpostController,
waitOn:function () {
return Meteor.subscribe('subheader', 'home');
}
});
The publish function appears to work fine.
Meteor.publish('subheader', function(cat) {
return Subheader.find({category: cat});
});
The correct doc from the mongodb collection is reaching the client. this can be seen by
Subheader.findOne(); output Object {_id: "NPo5cwqgjYY6i9rtx", texth: "ex text", category: "home"}
The problem starts here
The template loaded by the Controller in this case MissionstatementpostController is postlist
<template name="postsList">
<div class="posts page">
{{> subheader}}
<div class="wrapper">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
{{#if nextPath}}
<a class="load-more" href="{{nextPath}}">Load more</a>
{{else}}
{{#unless ready}}
{{> spinner}}
{{/unless}}
{{/if}}
</div>
</template>
Here is the subheader template
<template name="subheader">
<div class="container">
<p>{{{texth}}}</p>
</div>
</template>
So what did I mess-up?
thanks
you must create a template helper for your subheader template. To return just the texth field, the helper will be like this.
Template.subheader.helpers({
texth: function() {
var sh = Subheader.findOne();
return sh && sh.texth;
}
});
You can return the whole document and use the #with helper inside the template.
Template.subheader.helpers({
subh: function() {
return Subheader.findOne();
}
});
<template name="subheader">
{{#with subh}}
<div class="container">
<p>{{{texth}}}</p>
</div>
{{/with}}
</template>
You can find more info about template helpers on Meteor Docs.

Categories