This article was originally posted here
The source code has been updated to use Angular 5.
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 :)
→ Have NodeJs and npm on your system
→ To use this article I recommend you to follow Readme instructions
→ 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
app.component.css
app.component.html
→ 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:
→ 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:
File api.js presents in folder ./server/routes
Import the api file
// 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)
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);});});
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 CRUD gists
Follow me on Facebook, Twitter, LinkedIn and visit my blog.
Cheers!