Created
March 7, 2016 22:39
-
-
Save jack-guy/c7117eab219e0a893453 to your computer and use it in GitHub Desktop.
How to set up a Socket.io-based Feathers app with Angular 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {Injector} from 'angular2/core'; | |
| let appInjectorRef: Injector; | |
| export const appInjector = (injector?: Injector):Injector => { | |
| if (injector) { | |
| appInjectorRef = injector; | |
| } | |
| return appInjectorRef; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {SocketService} from './feathers.service'; | |
| import {appInjector} from './app-injector'; | |
| document.addEventListener('DOMContentLoaded', function main() { | |
| bootstrap(MyMainComponent, [ | |
| // Other stuff you need | |
| SocketService | |
| ]).then((appRef: ComponentRef) => { appInjector(appRef.injector); }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {Injectable} from 'angular2/core'; | |
| import {Observable, Subject} from 'rxjs'; | |
| const io = require('socket.io-client'); | |
| const feathers = require('feathers/client'); | |
| const socketio = require('feathers-socketio/client'); | |
| const localstorage = require('feathers-localstorage'); | |
| const hooks = require('feathers-hooks'); | |
| const authentication = require('feathers-authentication/client'); | |
| @Injectable() | |
| export class SocketService { | |
| public socket: SocketIOClient.Socket; | |
| public connectSubject: Subject<boolean> = new Subject(); | |
| protected _app: any; | |
| private _loggedIn: boolean = false; | |
| private _isConnected: boolean = false; | |
| constructor() { | |
| this.socket = io(HOST); | |
| this._app = feathers() | |
| .configure(socketio(this.socket)) | |
| .configure(hooks()) | |
| .use('storage', localstorage()) | |
| .configure(authentication()); | |
| this.socket.on('connected', () => { | |
| this.connectSubject.next(true); | |
| }); | |
| } | |
| checkAuth() { | |
| return Observable.of(this._loggedIn); | |
| } | |
| login (username, password) { | |
| return this._app.authenticate({ | |
| type: 'local', | |
| username: username, | |
| password: password | |
| }).then(() => { this._loggedIn = true; }); | |
| } | |
| logout () { | |
| return this._app.logout().then(() => { | |
| this._loggedIn = false; | |
| }); | |
| } | |
| refreshToken (token) { | |
| return this._app.authenticate({ | |
| type: 'token', | |
| token: token | |
| }).then(() => { this._loggedIn = true; }); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {Injector} from 'angular2/core'; | |
| import {Router, ComponentInstruction} from 'angular2/router'; | |
| import {appInjector} from './app-injector'; | |
| import {SocketService} from './feathers.service'; | |
| export const isLoggedIn = (next: ComponentInstruction, previous: ComponentInstruction) => { | |
| let injector: Injector = appInjector(); // get the stored reference to the injector | |
| let router: Router = injector.get(Router); | |
| let socketService: SocketService = injector.get(SocketService); | |
| // return a boolean or a promise that resolves a boolean | |
| return new Promise((resolve) => { | |
| // Wait until the socketService is connected, then check authentication | |
| socketService.connectSubject.first((x) => x).concat( | |
| socketService.checkAuth().take(1) | |
| ) | |
| .subscribe((isLoggedIn) => { | |
| // We're good! | |
| if (isLoggedIn) { | |
| resolve(true); | |
| } else { | |
| // Attempt to refresh the token we've got | |
| socketService.getToken().then(token => { | |
| socketService.refreshToken(token).then(() => { | |
| resolve(true); | |
| }).catch(e => { | |
| router.navigate(['/Login']); | |
| resolve(false); | |
| }); | |
| }).catch(e => { | |
| router.navigate(['/Login']); | |
| resolve(false); | |
| }); | |
| } | |
| }); | |
| }); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {isLoggedIn} from './is-logged-in.ts'; | |
| import {ComponentInstruction, CanActivate} | |
| @Component({ | |
| selector: 'app' | |
| }) | |
| @CanActivate((next: ComponentInstruction, previous: ComponentInstruction) => { | |
| return isLoggedIn(next, previous); | |
| }) | |
| export class YourProtectedRoute {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment