[Tutorial] An Introduction to Node.js Servers (and Express.js)

Thanks! I will try some things and report back! :slight_smile:

1 Like

I started writing it already, so I might be able to post something tonight. I’m curious about how it works. :slight_smile:

1 Like

Sounds good. Thanks! I am working on looping through a db query…hmmm

This should at least provide an example of how to start: [Tutorial] How to use subdomains in Express.js with vhost

If you have questions, let me know. I could also walk through it with screensharing if that would help.

1 Like

I am now working with handlebars and have a question about how do you register and use handlebars helpers?

For example I want to add this helper that will offset the index in a loop. (Add +1 to the index of a loop)

But I am not sure where to put the helper function.

Looking at the hbs docs, it looks like you can register them in the app.js file.

Here’s an example of code that I added to a branch in one of the sample repos:

These are the three changes:

// add this to the top of your app.js file
const hbs = require("hbs");

Then, after you set the view engine to hbs, define your helpers like this.

// increment a number by 1
hbs.registerHelper("increment", function (num, options) {
    return num + 1;
});

In your Handlebars template, you can use the helper by whatever name you gave it. This will increment the index by 1 by using increment (defined above). The period means to print the current item in an array. If you are using a JS object there, you could use the object key.

{{#each someArray}}
    {{increment @index}}: {{.}}
{{/each}}

Awesome, that worked, thanks!
I guess if I start to register more helpers I can put them in a file in the views folder and then use module imports and exports?

Slowly getting the hang of that. :slight_smile:

1 Like

This should work:

Create a directory next to app.js named handlebars and put an index.js file inside of it with this inside.

const hbs = require("hbs");

function initHandlebars() {
    // register a helper
    hbs.registerHelper("increment", function (num, options) {
        return num + 1;
    });

    // Register other handlebars things here. 
}

module.exports = initHandlebars;

Then put this at the top of your app.js file.

const initHandlebars = require("./handlebars");

Right after you set the view engine in app.js, add this line:

initHandlebars();

The link below has an example of working code.

Edit: if calling the directory handlebars is confusing, you could call it something else.

1 Like

I will try it. Thanks! :slight_smile:
At first, I was resistant, but now I really like the idea of helper functions.

1 Like

I am running into an issue now where I want to share JS helper functions between the controller (server side) and then subsequent renders on the client side.

The controller has its own folder and the helper functions are subfolders. But I want some of those helper functions to also be static JS functions on the client side.

What is the best way to structure this?

Should I move the controller folder/files into the view folder so the backend and frontend can share the JS functions?

Another wrinkle to this is that I like javascript to be inlined to save a file load. Though thinking about it now, I can probably bundle it and then have it lazy load 3 seconds after the page loads. :thinking:

Josh, if you have time for a call later today to talk this over I would appreciate it!

Sure, I could get on a call today. Send me a chat message.

You could solve it by putting your code into an npm package that gets imported into both the frontend and backend. You would need a build process for the frontend, but it wouldn’t have to be complicated. A built process would also minify your code before inlining it. Parcel is one that is easy to use — unlike webpack there is little to no configuration needed.

1 Like

Interesting! I will send a message. Thanks! :slight_smile:

1 Like

Firefox developer mode keeps crashing whenever I download it so I just stick to regular Firefox for development. Does that happen for anyone else?

@Josh or @Paul do you use mock functions or jest to test your servers? How often do you use a testing framework for your servers?

It’s working okay for me on Ubuntu 16.04. I was using Firefox Nightly as my main browser for a while and that finally crashed after a couple of years so I went back to regular Firefox. I’m using Firefox Developer Edition for most development at the moment though.

I think the main differences are that Developer Edition is currently version 78.0b1 and my regular Firefox is version 76.0.1. There’s also a different theme.

I have a few Firefox profiles, each with different extensions and settings. My Developer Edition has the fewest extensions, so that they don’t interfere with the code I’m writing.

I don’t test enough but I’m trying to do it more.

1 Like

Why the interest in handle bars? Was there some bottleneck you ran into with just vanilla Express and Node? Or do you just like the library?

I’m not sure if the question is for me or Paul, but I use Handlebars with Express, because I like it better than the other templating engines for Express. :slight_smile:

Handlebars is easy to use with express-generator like this:

$ express --view=hbs project_name

The default templating engine in Express is Pug, but you can pick from many options.

Pug doesn’t really appeal to me, because I like my templates to look something like HTML. (Just a personal preference.)

Ejs is another common templating engine for Express, but it requires more typing. I think this is how you iterate in ejs:

<% posts.forEach(function(post) { %>
    <h1><%= post.title %></h2>
    <div><%= post.body %></div>
<% }); %>

This is the same thing in Handlebars:

{{#each posts}}
    <h1>{{title}}</h2>
    <div>{{body}}</div>
{{/each}}

I don’t really have major complaints about ejs, but I would rather type and read {{/each}} than <% }); %>. :slight_smile:

For the sample output above, ejs required 154% more typing than Handlebars, not including the number of times I had to reach for easy-to-miss characters like %.

It might be possible to reduce the typing in ejs a little more by using shorter names, but even this is 134% more typing than the Handlebars version:

<% posts.forEach(p => { %>
    <h1><%= p.title %></h2>
    <div><%= p.body %></div>
<% }); %>

Pug also requires less typing, but it doesn’t look like HTML, and it has been a headache for me to debug when the nesting is wrong.

Handlebars also works on the frontend — this forum’s UI is rendered with Handlebars (Ember.js).

1 Like

Ok thank you, I was about to start a project that uses ejs and I wasn’t really sure if there was any trade off in performance or just personal preference with the different templates. I think handlebars seems easier to work with in my opinion.

1 Like

Oops, I am coming here late! Here are my answers @greenc123

Yeah, like Josh I don’t do any automated testing. I just refresh the browser page for now. I guess as projects get more complicated, writing automated tests before deployment would make sense.

Right now I am running an Apache server, which I think has a lot of what would be called “middle ware” out of the box. It is basically a robust server management software with a lot of features, and Liquid Web manages it for me.

Soon I am going to migrate to a Node server on something like Digital Ocean, so testing the server and other middleware operations will be something to think about.

As for Handlebars I am using it on Josh’s recommendation.
It is pretty similar to PHP, but with PHP you have the server insert content using echo statements like

$statement = 'Hello World';
<?php echo statement; ?>

In Handlebars it is

var statement='Hello World';

{{statement}}

So handlebars is pretty clean, and works with Javascript. I am moving to Javascript so I don’t have to maintain logic in both PHP and Javascript.

On the client side I am not using handlebars, I am just writing my own vanilla JS that manipulates the DOM using things like document.getElementById and so on…

What is your new project going to be about?

1 Like

I test Express with mocha and chai.

2 Likes