A small starter app built with MEAN2 and socket.io

This article was originally posted here

The source code has been updated to use Angular 5.

Summary

Build a simple real-time application that you can use as a starter to do what you want with MEAN2(MongoDB, Express, Angular2 & NodeJS), within the project will also be Socket.io, Typescript and Angular-material2.

After having worked with Angular2 and socket.io I faced some challenges that motivated me to build a simple starter project that I will reuse every times if need be.

I suppose that you already know the power of Ajax to build SPA application. But now there is a new protocol, not attached to the browser and it’s called socket.

Notes

Let’s call it gistology: https://gistology.herokuapp.com :)

Recommandations

→ Have NodeJs and npm on your system

→ To use this article I recommend you to follow Readme instructions

Demo

What is used

Client Side

Start App Architecture: Angular CLI

First you will need to install AngularCLI, to get started here is the link.

Now via your browser access the app here: http://localhost:4200

Generate client side components to manage gists:

Now we will still use the power of angular-cli to come out with a new component that will help us to manage gists, with this command:

ng g component gist

Output:

Include Angular-material2

Click here to get all steps.

Don’t forget to also install and load @angular/animation to enable some material components to work normally.

Include Angular-flexLayout

Design the home page: angular material card and list

→ Include Angular2-toaster for notifications

npm install — save angular2-toaster

@import ‘~angular2-toaster/toaster.css’;

/*** Model for gist*/export class Gist{

**constructor(public title, public description, public technologies, public link){

}**

}

→ Include socket.io-client

Now we need to add this @types in ./src/tsconfig.app.json and ./src/tsconfig.spec.json in the array types.

FILE tsconfig.app.json

{“extends”: “../tsconfig.json”,“compilerOptions”: {“outDir”: “../out-tsc/app”,“module”: “es2015”,“baseUrl”: “”,“types”: [“socket.io-client”]},“exclude”: [“test.ts”,“**/*.spec.ts”]}

Install it is very easy, we just have a simple command to type. Now we can create a simple service to emit and handle socket events, lets call it app.socketIo.service.ts in folder ./src/app:

Server Side

Install packages

npm install --save express body-parser http-status mongoose socket.io

Update file architecture for the server side code to add model and api.

Create a file we will use to run our application, we can call it index.js on the root folder. The trick here is to serve statics files as expected, let the /api root path for our api and all others request will be redirect to the index file present in dist folder when running the app; without forgetting to instantiate the socket.io server and handle some events to make sure all clients get them. The mongoose lib here will connect us to a mongo DB and allows us to define the server model.

In the index.js file we have:

→ Gist model: ./server/models/gist.js

Let’s do something really simple, all gists with a model with follow properties: title, description, technologies and the link.

→ To import mongoose and pass the db name to connect

var mongoose = require(‘mongoose’);

mongoose.connect(‘mongodb://localhost/gistology’); // A local db is used(gistology)

→ Build a little rest api for gists:

// Get gist routeconst api = require(‘./server/routes/api’);

Note: in the index.js file up there we done something like that.

→ Test the project:

Test the API: curl http://localhost:3000/api/gist returns an empty array([]) as I don’t yet create any gist(Yes the db is still empty)

Setup and run Socket.io Server:

File: ./index.js

const express = require(‘express’);const http = require(‘http’);const app = express();

/*** Create HTTP server and start the connect the socket*/

const server = http.createServer(app);// Socket.io for real time communication

var io = require(‘socket.io’).listen(server);

/*** Socket events*/

io.sockets.on(‘connection’, function(socket){console.log(‘Socket connected’);// Socket event for gist createdsocket.on(‘gistSaved’, function(gistSaved){io.emit(‘gistSaved’, gistSaved);});

// Socket event for gist updatedsocket.on(‘gistUpdated’, function(gistUpdated){io.emit(‘gistUpdated’, gistUpdated);});});

Handle gist rest requests with @angular/httprxjs

File: ./src/app/gist/gist.service.ts

import { Gist } from ‘./gist.model’;import { Injectable } from ‘@angular/core’;import { Http } from ‘@angular/http’;import ‘rxjs/add/operator/map’;

@Injectable()export class GistService {constructor(private http: Http) {}

// Get all saved gistsgetAllGists(){return this.http.get(‘/api/gist’).map(res => res.json());}

// Get a gist by IdgetGistById(gistId){return this.http.get(‘/api/gist/’ + gistId).map(res => res.json());}

// register a new gistpostGist(gist: Gist){return this.http.post(‘/api/gist’, gist).map(res => res.json());}

// update a gistupdateGist(gist: Gist){return this.http.put(‘/api/gist’, gist).map(res => res.json());}

}

// Some imports …import { GistService } from ‘./gist/gist.service’;

@NgModule({declarations: […],imports: […],providers: [GistService],bootstrap: [AppComponent]})export class AppModule { }

Ui to manage Gist: list, create, show and delete

UI to CRUD gists

Resources

Thanks for reading this post, recommend and share if you enjoyed it.

Follow me on Facebook, Twitter, LinkedIn and visit my blog.

Cheers!