├── server ├── database.js ├── routes │ └── employee.routes.js ├── models │ └── employee.js ├── index.js └── controllers │ └── employees.controller.js ├── package.json ├── .gitignore └── README.md /server/database.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const mongoose=require('mongoose') 4 | 5 | const URI='mongodb://127.0.0.1/mean-crud' 6 | 7 | mongoose.connect(URI) 8 | .then(db=>console.log('DB is connected!')) 9 | .catch(err=>console.error(err)) 10 | 11 | module.exports=mongoose 12 | 13 | -------------------------------------------------------------------------------- /server/routes/employee.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const express = require('express') 4 | 5 | const route = express.Router() 6 | 7 | const employee = require('../controllers/employees.controller') 8 | 9 | route.get('/', employee.getEmployees) 10 | route.get('/:productId', employee.getEmployeeById) 11 | route.post('/', employee.createEmployee) 12 | route.put('/:productId', employee.editEmployee) 13 | route.delete('/:productId', employee.deleteEmployee) 14 | 15 | 16 | module.exports = route -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mean", 3 | "version": "1.0.0", 4 | "description": "Software of development with Stack MEAN", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "nodemon server/index.js" 8 | }, 9 | "keywords": [], 10 | "author": "Daniel Alejo Alvarez", 11 | "license": "MIT", 12 | "dependencies": { 13 | "cors": "^2.8.4", 14 | "express": "^4.16.3", 15 | "mongoose": "^5.3.0", 16 | "morgan": "^1.9.1" 17 | }, 18 | "devDependencies": { 19 | "nodemon": "^1.18.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /server/models/employee.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const mongoose=require('mongoose') 4 | 5 | const { Schema }=mongoose 6 | 7 | const EmployeeSchema=new Schema({ 8 | displayName: { type: String, required: true}, 9 | scrumPosition: { type: String, enum: ['Product Owner','Development Team','Scrum Master'], required: true}, 10 | salary: { type: Number, required: true}, 11 | avatar: { type: String, required: true}, 12 | state: { type: Boolean, default: true} 13 | }) 14 | 15 | module.exports=mongoose.model('Employee', EmployeeSchema) -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const express=require('express') 4 | const morgan=require('morgan') 5 | const cors=require('cors') 6 | 7 | 8 | const app=express() 9 | const port=process.env.PORT || 3000 10 | 11 | const { mongoose }=require('./database') 12 | const api=require('./routes/employee.routes') 13 | 14 | //MIDDLEWARES 15 | app.use(morgan('dev')) 16 | app.use(express.json()) 17 | app.use(cors({ 18 | origin: 'http://127.0.0.1:4200' 19 | })) 20 | 21 | // app.get('/', (req,res)=>{ 22 | // res.send('Hello World!'); 23 | // }) 24 | //app.use(require('./routes/employee.routes')) 25 | app.use('/api/employees',api) 26 | 27 | app.listen(port, ()=>{ 28 | console.log(`Server running in port: ${port}`) 29 | }) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (https://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | 43 | # TypeScript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | 64 | # parcel-bundler cache (https://parceljs.org/) 65 | .cache 66 | 67 | # next.js build output 68 | .next 69 | 70 | # nuxt.js build output 71 | .nuxt 72 | 73 | # vuepress build output 74 | .vuepress/dist 75 | 76 | # Serverless directories 77 | .serverless -------------------------------------------------------------------------------- /server/controllers/employees.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Employee=require('../models/employee') 4 | 5 | const EmploCtrl={} 6 | 7 | 8 | EmploCtrl.getEmployees=async(req,res)=>{ 9 | /* res.json({ 10 | status: 'API works!' 11 | }) */ 12 | const employees=await Employee.find() 13 | res.json(employees) 14 | } 15 | 16 | EmploCtrl.getEmployeeById=async(req,res)=>{ 17 | const employee=await Employee.findById(req.params.productId) 18 | res.json(employee) 19 | } 20 | 21 | 22 | EmploCtrl.createEmployee=async(req,res)=>{ 23 | const employee = new Employee({ 24 | displayName: req.body.displayName, 25 | scrumPosition: req.body.scrumPosition, 26 | salary: req.body.salary, 27 | avatar: req.body.avatar, 28 | state: req.body.state 29 | }) 30 | await employee.save() 31 | res.json({ 32 | status: 'Employee saved!' 33 | }) 34 | } 35 | 36 | EmploCtrl.editEmployee=async(req,res)=>{ 37 | const { productId }=req.params 38 | const employee={ 39 | displayName: req.body.displayName, 40 | scrumPosition: req.body.scrumPosition, 41 | salary: req.body.salary, 42 | avatar: req.body.avatar, 43 | state: req.body.state 44 | } 45 | await Employee.findByIdAndUpdate(productId, {$set: employee}, {new: true}) 46 | res.json({ 47 | status: 'Employee updated!' 48 | }) 49 | } 50 | 51 | 52 | 53 | EmploCtrl.deleteEmployee=async(req,res)=>{ 54 | const { productId }=req.params 55 | await Employee.findByIdAndRemove(productId) 56 | res.json({ 57 | status: 'Employee deleted!' 58 | }) 59 | } 60 | 61 | module.exports=EmploCtrl 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STACKMEAN 2 | ## Description 3 | 4 | This repository is a Application software with MongoDB, Express, Angular and NodeJS, this application contains an API created with Express. 5 | 6 | ## Installation 7 | Using Angular 6 preferably. 8 | 9 | ## DataBase 10 | Using MongoDB preferably. 11 | 12 | ## Apps 13 | Using POSTMAN or RestEasy to feed the api. 14 | 15 | ## Usage 16 | ```html 17 | $ git clone https://github.com/DanielArturoAlejoAlvarez/STACKMEAN.git [NAME APP] 18 | 19 | $ npm install 20 | 21 | $ npm run dev (in Server) 22 | 23 | $ [NAME APP]/client npm install 24 | 25 | $ ng serve (in Client) 26 | ``` 27 | Follow the following steps and you're good to go! Important: 28 | 29 | 30 | ![alt text](http://res.cloudinary.com/dk1rn2kmf/image/upload/v1486523096/angular2-switcher_dif1ze.gif) 31 | 32 | 33 | ## Coding 34 | 35 | ## CLIENT 36 | 37 | ### SERVICES 38 | 39 | ```typescript 40 | ... 41 | export class EmployeeService { 42 | 43 | selectedEmployee: Employee 44 | 45 | employees: Employee[] 46 | 47 | readonly API_URL="http://127.0.0.1:3000/api/employees" 48 | 49 | constructor(private _http: HttpClient) { 50 | this.selectedEmployee=new Employee() 51 | } 52 | 53 | getEmployees(){ 54 | return this._http.get(this.API_URL) 55 | } 56 | 57 | postEmployee(Employee: Employee){ 58 | return this._http.post(this.API_URL, Employee) 59 | } 60 | 61 | putEmployee(employee: Employee){ 62 | return this._http.put(this.API_URL + `/${employee._id}`, employee) 63 | } 64 | 65 | deleteEmployee(_id: string){ 66 | return this._http.delete(this.API_URL + `/${_id}`) 67 | } 68 | 69 | } 70 | ... 71 | ``` 72 | 73 | ### COMPONENTS 74 | 75 | ```typescript 76 | ... 77 | addEmployee(form: NgForm){ 78 | //console.log(form.value) 79 | if(form.value._id){ 80 | this._employeeService.putEmployee(form.value) 81 | .subscribe(res=>{ 82 | this.resetForm(form) 83 | //M.toast({html: 'Updated successfully!'}) 84 | this._toastr.success('Updated successfully!'); 85 | this.getEmployees() 86 | this.txtToggle='CREATE EMPLOYEE' 87 | }) 88 | }else{ 89 | this._employeeService.postEmployee(form.value) 90 | .subscribe(res=>{ 91 | this.resetForm(form) 92 | //console.log(res) 93 | //M.toast({ html: 'Saved successfully!'}); 94 | this._toastr.success('Saved successfully!'); 95 | this.getEmployees() 96 | }) 97 | } 98 | } 99 | ... 100 | ``` 101 | 102 | 103 | ## API 104 | 105 | ### Controllers 106 | 107 | 108 | ```javascript 109 | ... 110 | EmploCtrl.createEmployee=async(req,res)=>{ 111 | const employee = new Employee({ 112 | displayName: req.body.displayName, 113 | scrumPosition: req.body.scrumPosition, 114 | salary: req.body.salary, 115 | avatar: req.body.avatar, 116 | state: req.body.state 117 | }) 118 | await employee.save() 119 | res.json({ 120 | status: 'Employee saved!' 121 | }) 122 | } 123 | ... 124 | 125 | ``` 126 | 127 | ### ROUTES 128 | 129 | ```javascript 130 | ... 131 | route.get('/', employee.getEmployees) 132 | route.get('/:productId', employee.getEmployeeById) 133 | route.post('/', employee.createEmployee) 134 | route.put('/:productId', employee.editEmployee) 135 | route.delete('/:productId', employee.deleteEmployee) 136 | ... 137 | ``` 138 | 139 | ### Model 140 | 141 | ```javascript 142 | ... 143 | const mongoose=require('mongoose') 144 | 145 | const { Schema }=mongoose 146 | 147 | const EmployeeSchema=new Schema({ 148 | displayName: { type: String, required: true}, 149 | scrumPosition: { type: String, enum: ['Product Owner','Development Team','Scrum Master'], required: true}, 150 | salary: { type: Number, required: true}, 151 | avatar: { type: String, required: true}, 152 | state: { type: Boolean, default: true} 153 | }) 154 | 155 | module.exports=mongoose.model('Employee', EmployeeSchema) 156 | ... 157 | ``` 158 | 159 | ## Contributing 160 | 161 | Bug reports and pull requests are welcome on GitHub at https://github.com/DanielArturoAlejoAlvarez/STACKMEAN. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. 162 | 163 | 164 | ## License 165 | 166 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). --------------------------------------------------------------------------------