├── .gitignore ├── img ├── app.png └── issue_01.png ├── config.js ├── public └── app │ ├── directives │ └── reverse.js │ ├── app.js │ ├── services │ ├── userService.js │ ├── storyService.js │ └── authService.js │ ├── views │ ├── pages │ │ ├── allStories.html │ │ ├── login.html │ │ ├── signup.html │ │ └── home.html │ └── index.html │ ├── controllers │ ├── userCtrl.js │ ├── storyCtrl.js │ └── mainCtrl.js │ └── app.routes.js ├── app ├── models │ ├── story.js │ └── user.js └── routes │ └── api.js ├── package.json ├── server.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | node_modules 3 | *.log 4 | -------------------------------------------------------------------------------- /img/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webmakaka/Build-a-Real-Time-web-app-in-node.js-Angular.js-mongoDB/HEAD/img/app.png -------------------------------------------------------------------------------- /img/issue_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/webmakaka/Build-a-Real-Time-web-app-in-node.js-Angular.js-mongoDB/HEAD/img/issue_01.png -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "database": "mongodb://root:root@ds031661.mlab.com:31661/userstory", 3 | "port": process.env.PORT || 3000, 4 | "secretKey": "YourSecretKey" 5 | }; 6 | -------------------------------------------------------------------------------- /public/app/directives/reverse.js: -------------------------------------------------------------------------------- 1 | angular.module('reverseDirective', []) 2 | .filter('reverse', function(){ 3 | return function(items){ 4 | return items.slice().reverse(); 5 | }; 6 | }); 7 | -------------------------------------------------------------------------------- /public/app/app.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('MyApp', ['appRoutes', 'mainCtrl', 'authService', 'userCtrl', 'userService', 'storyService', 'storyCtrl', 'reverseDirective']) 3 | .config(function($httpProvider){ 4 | $httpProvider.interceptors.push('AuthInterceptor'); 5 | }); 6 | -------------------------------------------------------------------------------- /app/models/story.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | var Schema = mongoose.Schema; 4 | 5 | var StorySchema = new Schema({ 6 | 7 | creator: {type: Schema.Types.ObjectId, fef: 'User'}, 8 | content: String, 9 | creted: {type: Date, default: Date.now} 10 | 11 | }); 12 | 13 | module.exports = mongoose.model('Story', StorySchema); 14 | -------------------------------------------------------------------------------- /public/app/services/userService.js: -------------------------------------------------------------------------------- 1 | angular.module('userService', []) 2 | .factory('User', function($http){ 3 | var userFactory = {}; 4 | userFactory.create = function(userData){ 5 | return $http.post('/api/signup', userData); 6 | }; 7 | 8 | userFactory.all = function(){ 9 | return $http.get('/api/users'); 10 | }; 11 | 12 | return userFactory; 13 | }); 14 | -------------------------------------------------------------------------------- /public/app/views/pages/allStories.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 |
9 |
10 | 11 |
Your Stories
12 | 13 |
14 |

{{ each.content }}

15 |
16 |
17 |
18 |
19 | 20 | 21 |
22 | 23 |
24 | 25 |
26 | -------------------------------------------------------------------------------- /public/app/views/pages/login.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 |

Login

7 | 8 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /public/app/views/pages/signup.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |

Signup!

6 | 7 |
8 | 9 | Name: 10 | Username: 11 | Password: 12 | 13 | 14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /public/app/controllers/userCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('userCtrl', ['userService']) 2 | 3 | .controller('UserController', function(User){ 4 | var vm = this; 5 | 6 | User.all() 7 | .success(function(data){ 8 | vm.users = data; 9 | }); 10 | }) 11 | 12 | 13 | .controller('UserCreateController', function(User, $location, $window){ 14 | var vm = this; 15 | vm.singupUser = function(){ 16 | vm.message = ''; 17 | User.create(vm.userData) 18 | .then(function(response){ 19 | vm.userData = {}; 20 | vm.message = response.data.message; 21 | $window.localStorage.setItem('token', response.data.token); 22 | $location.path('/'); 23 | }); 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /app/models/user.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var Schema = mongoose.Schema; 3 | var bcrypt = require('bcrypt-nodejs'); 4 | 5 | var UserSchema = new Schema({ 6 | name: String, 7 | username: { type: String, required: true, index: { unique: true }}, 8 | password: { type: String, required: true, select: false} 9 | }); 10 | 11 | UserSchema.pre('save', function(next){ 12 | var user = this; 13 | if(!user.isModified('password')) return next(); 14 | 15 | bcrypt.hash(user.password, null, null, function(err, hash){ 16 | if(err) return next(err); 17 | 18 | user.password = hash; 19 | next(); 20 | }); 21 | }); 22 | 23 | UserSchema.methods.comparePassword = function(password){ 24 | var user= this; 25 | return bcrypt.compareSync(password, user.password); 26 | }; 27 | 28 | module.exports = mongoose.model('User', UserSchema); 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "userStory", 3 | "version": "1.0.0", 4 | "description": "[udemy] Build a Real Time web app in node.js , Angular.js, mongoDB", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/marley-nodejs/Build-a-Real-Time-web-app-in-node.js-Angular.js-mongoDB" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/marley-nodejs/Build-a-Real-Time-web-app-in-node.js-Angular.js-mongoDB/issues" 17 | }, 18 | "homepage": "https://github.com/marley-nodejs/Build-a-Real-Time-web-app-in-node.js-Angular.js-mongoDB", 19 | "dependencies": { 20 | "bcrypt-nodejs": "0.0.3", 21 | "body-parser": "^1.12.2", 22 | "bson": "^0.5.7", 23 | "express": "^4.12.3", 24 | "jsonwebtoken": "^4.2.1", 25 | "mongoose": "^4.1.11", 26 | "morgan": "^1.5.2", 27 | "socket.io": "^1.3.5" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /public/app/controllers/storyCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('storyCtrl', ['storyService']) 2 | .controller('StoryController', function(Story, socketio){ 3 | 4 | vm = this; 5 | 6 | Story.allStory() 7 | .success(function(data){ 8 | vm.stories = data; 9 | }); 10 | 11 | vm.createStory = function(){ 12 | vm.message = ''; 13 | Story.create(vm.storyData) 14 | .success(function(data){ 15 | 16 | // clear up the form 17 | vm.storyData = ''; 18 | vm.message = data.message; 19 | }); 20 | }; 21 | 22 | socketio.on('story', function(data){ 23 | vm.stories.push(data); 24 | }); 25 | }) 26 | 27 | .controller('AllStoriesController', function(stories, socketio){ 28 | var vm = this; 29 | vm.stories = stories.data; 30 | 31 | socketio.on('story', function(data){ 32 | vm.stories.push(data); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var bodyParser = require('body-parser'); 3 | var morgan = require('morgan'); 4 | var config = require('./config.js'); 5 | var mongoose = require('mongoose'); 6 | 7 | var app = express(); 8 | 9 | var http = require('http').Server(app); 10 | var io = require('socket.io')(http); 11 | 12 | mongoose.connect(config.database, function(err){ 13 | if(err){ 14 | console.log(err); 15 | } else { 16 | console.log('connected to the database'); 17 | } 18 | }); 19 | 20 | app.use(bodyParser.urlencoded({extended: true})); 21 | app.use(bodyParser.json()); 22 | app.use(morgan('dev')); 23 | 24 | app.use(express.static(__dirname + '/public')); 25 | 26 | var api = require('./app/routes/api.js')(app, express, io); 27 | app.use('/api', api); 28 | 29 | app.get('*', function(req, res){ 30 | res.sendFile(__dirname + '/public/app/views/index.html'); 31 | }); 32 | 33 | http.listen(config.port, function(err){ 34 | if(err){ 35 | console.log(err); 36 | } else { 37 | console.log("Listening on port 3000"); 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /public/app/app.routes.js: -------------------------------------------------------------------------------- 1 | angular.module('appRoutes', ['ngRoute']) 2 | .config(function($routeProvider, $locationProvider){ 3 | $routeProvider 4 | .when('/', { 5 | templateUrl: 'app/views/pages/home.html', 6 | controller: 'MainController', 7 | controllerAs: 'main' 8 | }) 9 | .when('/login', { 10 | templateUrl: 'app/views/pages/login.html' 11 | }) 12 | .when('/signup', { 13 | templateUrl: 'app/views/pages/signup.html' 14 | }) 15 | .when('/allStories', { 16 | templateUrl: 'app/views/pages/allStories.html', 17 | controller: 'AllStoriesController', 18 | controllerAs: 'story', 19 | resolve: { 20 | stories: function(Story){ 21 | return Story.allStories(); 22 | } 23 | } 24 | }); 25 | 26 | $locationProvider.html5Mode({ 27 | enabled: true, 28 | requireBase: false 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /public/app/controllers/mainCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('mainCtrl', []) 2 | .controller('MainController', function($rootScope, $location, Auth){ 3 | 4 | var vm = this; 5 | 6 | vm.loggedIn = Auth.isLoggedIn(); 7 | $rootScope.$on('$routeChangeStart', function(){ 8 | vm.loggedIn = Auth.isLoggedIn(); 9 | Auth.getUser() 10 | .then(function(data){ 11 | vm.user = data.data; 12 | }); 13 | }); 14 | 15 | vm.doLogin = function(){ 16 | vm.processing = true; 17 | vm.error = ''; 18 | 19 | Auth.login(vm.loginData.username, vm.loginData.password) 20 | .success(function(data){ 21 | vm.processing = false; 22 | 23 | Auth.getUser() 24 | .then(function(data){ 25 | vm.user = data.data; 26 | }); 27 | 28 | if(data.success){ 29 | $location.path('/'); 30 | } else { 31 | vm.error = data.message; 32 | } 33 | }); 34 | }; 35 | 36 | vm.doLogout = function(){ 37 | Auth.logout(); 38 | $location.path('logout'); 39 | }; 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /public/app/services/storyService.js: -------------------------------------------------------------------------------- 1 | angular.module('storyService', []) 2 | .factory('Story', function($http){ 3 | var storyFactory = {}; 4 | 5 | storyFactory.allStories = function(){ 6 | return $http.get('/api/all_stories'); 7 | }; 8 | 9 | storyFactory.create = function(storyData){ 10 | return $http.post('/api', storyData); 11 | }; 12 | 13 | storyFactory.allStory = function(){ 14 | return $http.get('/api'); 15 | }; 16 | 17 | return storyFactory; 18 | 19 | }) 20 | 21 | .factory('socketio', function($rootScope){ 22 | var socket = io.connect(); 23 | return { 24 | on: function(eventName, callback){ 25 | socket.on(eventName, function(){ 26 | var args = arguments; 27 | $rootScope.$apply(function(){ 28 | callback.apply(socket, args); 29 | }); 30 | }); 31 | }, 32 | 33 | emit: function(eventName, data, callback){ 34 | var args = arguments; 35 | $rootScope.apply(function(){ 36 | if(callback){ 37 | callback.apply(socket,args); 38 | } 39 | }); 40 | } 41 | }; 42 | }); 43 | -------------------------------------------------------------------------------- /public/app/views/pages/home.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

if you have balls Sing up!

4 |
5 |
6 |

Login to write your story

7 | Login 8 |
9 | 10 |
11 | 12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 |
Write your Story
23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 | 31 |
Your Stories
32 | 33 |
34 |

{{ each.content }}

35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 | 45 |
46 | -------------------------------------------------------------------------------- /public/app/services/authService.js: -------------------------------------------------------------------------------- 1 | angular 2 | .module('authService', []) 3 | .factory('Auth', function($http, $q, AuthToken){ 4 | var authFactory = {}; 5 | 6 | authFactory.login = function(username, password){ 7 | 8 | console.log(username + " " + password); 9 | 10 | return $http.post('/api/login', { 11 | username: username, 12 | password: password 13 | }) 14 | .success(function(data){ 15 | AuthToken.setToken(data.token); 16 | return data; 17 | }); 18 | }; 19 | 20 | authFactory.logout = function(){ 21 | AuthToken.setToken(); 22 | }; 23 | 24 | authFactory.isLoggedIn = function(){ 25 | if(AuthToken.getToken()){ 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | }; 31 | 32 | authFactory.getUser = function(){ 33 | if(AuthToken.getToken()){ 34 | return $http.get('/api/me'); 35 | } else { 36 | return $q.reject({ message: "User has no token"}); 37 | } 38 | }; 39 | 40 | return authFactory; 41 | }) 42 | 43 | .factory('AuthToken', function($window){ 44 | var authTokenFactory = {}; 45 | 46 | authTokenFactory.getToken = function(){ 47 | return $window.localStorage.getItem('token'); 48 | }; 49 | 50 | authTokenFactory.setToken = function(token){ 51 | 52 | if(token){ 53 | $window.localStorage.setItem('token', token); 54 | } else { 55 | $window.localStorage.removeItem('token'); 56 | } 57 | }; 58 | 59 | return authTokenFactory; 60 | }) 61 | 62 | .factory('AuthInterceptor', function($q, $location, AuthToken){ 63 | var interceptorFactory = {}; 64 | 65 | interceptorFactory.request = function(config){ 66 | var token = AuthToken.getToken(); 67 | 68 | if(token){ 69 | config.headers['x-access-token'] = token; 70 | } 71 | 72 | return config; 73 | }; 74 | 75 | interceptorFactory.responseError = function(response){ 76 | if(response.status == 403){ 77 | $location.path('/login'); 78 | } 79 | return $q.reject(response); 80 | }; 81 | 82 | return interceptorFactory; 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /public/app/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | User Story 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 49 |
50 | 51 |
52 |
53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/routes/api.js: -------------------------------------------------------------------------------- 1 | var User = require('../models/user.js'); 2 | var Story = require('../models/story.js'); 3 | var config = require('../../config.js'); 4 | 5 | var secretKey = config.secretKey; 6 | 7 | var jsonwebtoken = require('jsonwebtoken'); 8 | 9 | function createToken(user){ 10 | var token = jsonwebtoken.sign({ 11 | id: user._id, 12 | name: user.name, 13 | username: user.username 14 | }, secretKey, { 15 | expiresInMinute: 1440 16 | }); 17 | 18 | return token; 19 | } 20 | 21 | module.exports = function(app, express, io){ 22 | var api = express.Router(); 23 | 24 | api.get('/all_stories', function(req, res){ 25 | Story.find({}, function(err, stories){ 26 | 27 | if(err){ 28 | res.send(err); 29 | return; 30 | } 31 | 32 | res.json(stories); 33 | }); 34 | }); 35 | 36 | api.post('/signup', function(req, res){ 37 | var user = new User({ 38 | name: req.body.name, 39 | username: req.body.username, 40 | password: req.body.password 41 | }); 42 | 43 | var token = createToken(user); 44 | 45 | user.save(function(err){ 46 | if(err){ 47 | res.send(err); 48 | return; 49 | } 50 | res.json({ 51 | success: true, 52 | message: 'User has been created', 53 | token: token 54 | }); 55 | }); 56 | }); 57 | 58 | api.get('/users', function(req, res){ 59 | User.find({}, function(err, users){ 60 | if(err){ 61 | res.send(err); 62 | return; 63 | } 64 | res.json(users); 65 | }); 66 | }); 67 | 68 | 69 | api.post('/login', function(req, res){ 70 | User.findOne({ 71 | username: req.body.username 72 | }).select('name username password').exec(function(err, user){ 73 | if(err) throw err; 74 | 75 | if(!user){ 76 | res.send({ message: "User doesn't exist"}); 77 | } else if (user){ 78 | var validPassword = user.comparePassword(req.body.password); 79 | 80 | if(!validPassword){ 81 | res.send({message: "Invalid Password"}); 82 | } else { 83 | // token 84 | var token = createToken(user); 85 | res.json({ 86 | success: true, 87 | message: "Successfully login", 88 | token: token 89 | }); 90 | } 91 | } 92 | }); 93 | }); 94 | 95 | api.use(function(req, res, next){ 96 | console.log("Somebody just came to our app!"); 97 | 98 | // var token = req.body.token || req.param('token') || req.headers['x-access-token']; 99 | var token = req.query['x-access-token'] || req.headers['x-access-token']; 100 | 101 | console.log("token: " + token); 102 | 103 | // check if token exist 104 | if(token){ 105 | jsonwebtoken.verify(token, secretKey, function(err, decoded){ 106 | if(err){ 107 | res.status(403).send({success: false, message: "Failed to authenticate user"}); 108 | } else { 109 | req.decoded = decoded; 110 | next(); 111 | } 112 | }); 113 | } else { 114 | res.status(403).send({success: false, message: "No token Provided"}); 115 | } 116 | 117 | }); 118 | 119 | // Destination B // provide a logitimate token 120 | 121 | api.route('/') 122 | .post(function(req, res){ 123 | var story = new Story({ 124 | creator: req.decoded.id, 125 | content: req.body.content 126 | }); 127 | story.save(function(err, newStory){ 128 | if(err){ 129 | res.send(err); 130 | return; 131 | } 132 | io.emit('story', newStory); 133 | res.json({message: "New Story Created!"}); 134 | }); 135 | }) 136 | .get(function(req, res){ 137 | Story.find({ creator: req.decoded.id}, function(err, stories){ 138 | if(err){ 139 | res.send(err); 140 | return; 141 | } 142 | res.json(stories); 143 | }); 144 | }); 145 | 146 | api.get('/me', function(req, res){ 147 | res.json(req.decoded); 148 | }); 149 | 150 | return api; 151 | }; 152 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Udemy] Build a Real Time web app in node.js, Angular.js, mongoDB 2 | 3 |
4 | 5 | I'm working on Ubuntu in docker container with debian jessie: 6 | 7 | $ lsb_release -a 8 | Distributor ID: Ubuntu 9 | Description: Ubuntu 14.04.5 LTS 10 | Release: 14.04 11 | Codename: trusty 12 | 13 | 14 |
15 | 16 | $ docker -v 17 | Docker version 1.9.1, build a34a1d5 18 | 19 |
20 | 21 | 22 | How to run docker container for start development 23 | (If link will not work give me to know about it) 24 | 25 |
26 | 27 | # node -v 28 | v6.8.1 29 | 30 | # npm -v 31 | 3.10.8 32 | 33 | 34 | 35 | Run Application: 36 | 37 | 38 | $ git clone application_name 39 | $ npm install 40 | $ npm start 41 | 42 | 43 | http://localhost:3000/login 44 | 45 | username: batman 46 | password: abc123 47 | 48 |
49 | 50 | ![Application](/img/issue_01.png?raw=true) 51 | 52 | 53 |
54 | 55 | If you will receive error: 56 | 57 | Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND' } js-bson: Failed to load c++ bson extension, using pure JS version 58 | 59 | 60 | Solution: 61 | 62 | http://stackoverflow.com/questions/28651028/cannot-find-module-build-release-bson-code-module-not-found-js-bson 63 | 64 | 65 | ____ 66 | 67 | Original src: 68 | https://github.com/arashdoescode/userStory 69 | 70 | ____ 71 | 72 | ## Server side 73 | 74 | ### 4_-_Start_your_first_project 75 | 76 | npm install --save express 77 | npm install --save body-parser 78 | npm install --save morgan 79 | 80 | nodemon server.js 81 | 82 | 83 | ### 5_-_Setting_up 84 | 85 | ### 6_-_Your_first_Hello_World 86 | 87 | http://localhost:3000/ 88 | 89 | ### 7_-_Create_a_database 90 | 91 | https://mongolab.com 92 | 93 | npm install --save mongoose 94 | 95 | 96 | ### 8_-_Your_first_Schema_-_Creating_User_Schema 97 | 98 | 99 | ### 9_-_Password_hashing 100 | 101 | npm install --save bcrypt-nodejs 102 | 103 | ### 10_-_Create_a_custom_method 104 | 105 | ### 11_-_Your_first_API_-_Signup_API 106 | 107 | postman 108 | 109 | POST -> localhost:3000/api/signup 110 | 111 | x-www-form-urlencoded 112 | 113 | name: Bruce 114 | username: batman 115 | password: abc123 116 | 117 | ### 12_-_Get_all_users_API 118 | 119 | http://localhost:3000/api/users 120 | 121 | ### 13_-_Login_API 122 | 123 | npm install --save jsonwebtoken 124 | 125 | postman 126 | 127 | POST -> localhost:3000/api/login 128 | 129 | x-www-form-urlencoded 130 | 131 | username: batman 132 | password: abc123 133 | 134 | 135 | ### 14_-_Create_a_custom_middleware (code not tested) 136 | 137 | 138 | ### 15_-_Test_the_middleware 139 | 140 | postman 141 | 142 | POST -> localhost:3000/api/login 143 | 144 | x-www-form-urlencoded 145 | 146 | username: batman 147 | password: abc123 148 | 149 | 150 | Headers 151 | 152 | GET -> localhost:3000/api/ 153 | 154 | URL Parameter Key: x-access-token 155 | Value: token 156 | 157 | 158 | ### 16_-_Your_second_Schema_-_Creating_Story_Schema (code not tested) 159 | 160 | 161 | ### 17_-_Post_method_in_Home_API 162 | 163 | 164 | 165 | postman 166 | 167 | GET -> localhost:3000/api/users 168 | POST -> localhost:3000/api/login 169 | 170 | __ 171 | 172 | POST -> localhost:3000/api/ 173 | URL Parameter Key: x-access-token 174 | Value: token 175 | 176 | x-www-form-urlencoded 177 | 178 | key: content 179 | value: Hello this is my first post! 180 | 181 | __ 182 | 183 | GET -> localhost:3000/api/ 184 | URL Parameter Key: x-access-token 185 | Value: token 186 | 187 | 188 | ### 18_-_Decoded_user_s_information (code not tested) 189 | 190 | ___ 191 | 192 | ## Frontend 193 | 194 | ### 19_-_Setup_the_front-end_files 195 | 196 | ### 20_-_First_Angular_Service_part_1_-_Creating_Auth_Factory (code not tested) 197 | 198 | ### 21_-_First_Angular_Service_part_2_-_Creating_AuthToken_Factory (code not tested) 199 | 200 | ### 22_-_First_Angular_Service_part_3_-_Creating_AuthInterceptor_Factory (code not tested) 201 | 202 | ### 23_-_First_Angular_Controller_-_Creating_Main_Controller_for_Login_and_Logout (code not tested) 203 | 204 | 205 | ### 24_-_Routing_System 206 | 207 | http://cdnjs.com/libraries/angular.js/ 208 | 209 | http://localhost 210 | 211 | 212 | ### 25_-_Login_Html 213 | 214 | ### 26_-_Signup_Frontend (Code not working! That's ok) 215 | 216 | ### 27_-_Testing_Login_and_Logout 217 | 218 | http://localhost:3000/login 219 | 220 | username: batman 221 | password: abc123 222 | 223 | 224 | ### 28_-_Fix_sIgnup_bugs 225 | 226 | ### 29_-_Creating_Story_service_and_controller_part_1_ 227 | ### 30_-_Creating_Story_service_and_controller_part_2_ 228 | 229 | ### 31_-_Adding_real-time_capability 230 | 231 | npm install --save socket.io 232 | 233 | ### 32_-_Getting_All_Stories 234 | 235 | http://localhost:3000/allStories 236 | 237 | ### 33_-_Creating_a_new_directive_-_reverse.js 238 | 239 | http://localhost:3000 240 | http://localhost:3000/allStories 241 | 242 | ### 34_-_Deploy_our_app_to_heroku 243 | 244 | ============================================ 245 | 246 | ![Application](/img/app.png?raw=true) 247 | 248 | 249 |
250 | 251 | --- 252 | 253 |
254 | 255 | **Marley** 256 | 257 | Any questions in english: Telegram Chat 258 | Любые вопросы на русском: Телеграм чат 259 | --------------------------------------------------------------------------------