Meteor Chat App

Create a Meteor chat app in 30 minutes

By on June 13, 2016

In the previous post, we’ve discovered the very basic of Meteor. Now let’s create something interesting like this:
demo
It’s a simple real-time chat, with many users. Follow these steps and you’ll finish it in just 30 minutes!

Where do I begin?

To create a Meteor app, simply open your terminal and run this command:

 meteor create simple-chat

Now try to run your first Meteor app:

cd simple-chat
meteor

Let’s check it out using your web browser: http://localhost:3000/

You’ve told that it’s all JavaScript, why does it look so strange?

Every new Meteor app includes Blaze, which is Meteor‚Äôs built-in reactive rendering library. Usually, templates are written in Spacebars. These templates are compiled into JavaScript UI components that are rendered by the Blaze library. I’ll continue to explain it later ūüėÄ

Now add some folders like this:
files2
This is the file structure that Meteor recommends us. You can find out more here.
Next, open client/main.html, replace all the code with this:

<head>
  <title>My Simple Chat</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</head>

We will write the body code in a new file. Let’s add some files to the imports/ui directory:
body.html

<body>
  <h3>SIMPLE METEOR CHAT</h3>
   <ul>
      {{#each messages}}
        {{> message}}
      {{/each}}
</ul>
</body>
<template name="message">
  <li>{{text}}</li>
</template>

and body.js

import { Template } from 'meteor/templating';
import './body.html';
Template.body.helpers({
  messages: [
    { text: 'Hello,' },
    { text: 'Nice to meet you!' },
    { text: '<3' },
  ],
});

Also open file client/main.js and replace all the codes with this:

 import '../imports/ui/body.js';

Then you will see something like this:
hello
You can see that Meteor renders the HTML with head section from <head> tag in main.html, body section from <body> tag in body.html. Look at the body, you will see this:

 {{#each messages}}
         {{> message}}
 {{/each}}

This is Spacebar syntax. Like I’ve explained before, Spacebar is a Meteor template language. It uses statements surrounded by double curly braces such as {{#each}} and {{#if}} to let you add logic and data to your views. (You can read more about Blaze and Spacebar).
So in the code above, each item from the messages collection will be put into template named message. Template in Meteor is just like Partial view in ASP.NET, it’s a chunk of HTML that can be safely inserted into an existing DOM. You can define it using this:

 <template name="templateName">
 #put template code here
 </template>

and reference in your JavaScript with Template.templateName. Furthermore, in your JavaScript, the body section can be referenced with Template.body. It’s a special “parent” template including the other child templates.
Now we have 3 messages, created by the Template.body.helpers in the body.js. So how can we can type message, send it and show in our app? We will figure out how to do it later.

Can we style it?

The easiest way is using Bootstrap. With Meteor, adding Bootstrap can be done in the blink of an eye. Open another terminal tab, go to the simple-chat directory and run this:

 meteor add twbs:bootstrap

Done! Now we can use Bootstrap. Replace your body.html code with this:

 <body>
   <div class="container">
     <div class="row">
       <h3 class="text-center" >SIMPLE METEOR CHAT</h3>
 	   	<!-- text holder -->
       <div class="col-md-12">
 		<!-- login button -->
         <div class="panel panel-info">
           <div class="panel-heading">
             GROUP CHAT
           </div>
           <div class="panel-body">
             <ul class="media-list">
               <!-- message template -->
               {{#each messages}}
                 {{> message}}
               {{/each}}
             </ul>
           </div>
           <!-- message textbox -->
           <form class="new-message">
             <div class="panel-footer">
               <div class="input-group">
                 <input type="text" name="text" class="form-control" placeholder="Enter Message" />
                 <span class="input-group-btn">
                   <button class="btn btn-info send" type="submit">SEND</button>
                 </span>
               </div>
             </div>
           </form>
         </div>
       </div>
     </div>
   </div>
 </body>

Then we will create several files in the imports/ui/ directory to separate each template to a different html file and js file.
Create new file message.html:

 <template name="message">
   <li class="media">
     <div class="media-body">
       <div class="media">
         <a class="pull-left" href="#">
         <img class="media-object img-circle img-responsive" src="https://lorempixel.com/60/60/people/" />
         </a>
         <div class="media-body" >
           {{text}}
          <br />
          <!-- user information -->
          <hr />
         </div>
       </div>
     </div>
   </li>
 </template>

Create new file message.js:

 import { Template } from 'meteor/templating';
 import './message.html';

Open body.js and add this after import './body.html':

 import './message.js';

Thank to Bootstrap we have such an elegant app:
bootstrap

Nice, but it doesn’t work, I can’t send message! Why oh why?

Don’t be too hurry! :-p . Now we will create a database collection to store the messages. Create a new file messages.js in the imports/api/ directory like this:

 import { Mongo } from 'meteor/mongo';
 export const Messages = new Mongo.Collection('messages');

In MongoDB, this is how we create a collection in JavaScript:

 MyCollection = new Mongo.Collection("my-collection")

On the server, this sets up a MongoDB collection called my-collection; on the client, this creates a cache connected to the server collection. In this demo, to make it easy, assume that the entire database is present on the client.

We also import the messages.js to the server. Open the server/main.js and add this to the second line:

 import '../imports/api/messages.js';

Now we can display message from the collection by opening body.js and replacing the Template.body.helpers with this:

 import { Messages } from '../api/messages.js';
 Template.body.helpers({
   messages() {
     return Messages.find();
   },
 });

Don’t worry when your chat group is empty. Just a few steps left then you will receive your messages. ūüėÄ
As we created the message textbox in the body.html in the previous step, now we will handle the submit event to insert new message. Add this to the end of the body.js:

 Template.body.events({
   'submit .new-message'(event) {
     // Prevent default browser form submit
     event.preventDefault();
     // Get value from form element
     const target = event.target;
     const text = target.text.value;
     // Insert a message into the collection
     Messages.insert({
       text,
       createdAt: new Date(), // current time
 	 //user information
     });
     // Clear form
     target.text.value = '';
     // scroll to last message
     $('.panel-body').scrollTop($('.media-list').height())
	},
 });

Now you can say Hello world!
hello-world You can open another browser window and chat to yourself to see if it works real-time. Awesome, right? ūüėÄ

This is not a chat. Everyone must have their own accounts and log in, right?

It’s simple man. If you think we have a lot of things to deal with, then you will be surprised. Just run this command:

meteor add accounts-ui accounts-password

This will enable Meteor accounts system and a drop-in login user interface with multi-user functionality.
Then open body.html and replace the <!-- text holder --> with this:

 <h5 class="text-center text-muted">Sign in to join!</h5>

and replace the <!-- login button --> with this:

 {{> loginButtons}}

And add this before and after the <form> tag:

 {{#if currentUser}}
 <form…>
 …
 </form>
 {{/if}}

Then we will add a new file accounts-config.js in the imports/startup/ directory to make easier to sign up:

 import { Accounts } from 'meteor/accounts-base';
 Accounts.ui.config({
   passwordSignupFields: 'USERNAME_ONLY',
 });

And import it by opening client/main.js and inserting this to the first line:

 import '../imports/startup/accounts-config.js';

Then you will see our app now looks like this:
signup
You can simply create account, sign in… To join our chat!
Let’s add some more fields to your messages collection to see who sends it. Open the body.js and replace //user informationinside the function Messages.insert with this:

 owner: Meteor.userId(), username:Meteor.user().username,

And open the message.html, replace the <!-- user information --> with this:

 <small class="text-muted"><strong>{{username}}</strong> | {{createdAt}}</small>

Finally, add this to client/main.css:

 .panel-body{
   overflow-y:scroll;
   height:60vh;
 }

All done! Enjoy your Meteor chat app!

Conclusion

Through this simple app, we’ve discovered something more about Meteor:

  • File structure in Meteor
  • Blaze – Meteor’s default frontend rendering system
  • Spacebar – Meteor’s template language
  • How to add packages to your Meteor app

Hope you find it useful. Keep practising everyday!

P.s: You can get the all code here. ūüėÄ

About Author

author

A little girl interested in programming and using new technologies to help working easier

Tag Cloud

Subscription

Statistics

  • Today Visitor: 107
  • Month Visit: 47,682
  • Total Posts: 68

Twitter Tweets

LikeBox

Facebook By Weblizar Powered By Weblizar
Shares