{"id":17137420,"url":"https://github.com/easingthemes/simple-nodejs","last_synced_at":"2025-03-24T07:16:19.533Z","repository":{"id":75134724,"uuid":"42393779","full_name":"easingthemes/simple-nodejs","owner":"easingthemes","description":"Simple nodejs crud","archived":false,"fork":false,"pushed_at":"2015-09-13T11:58:34.000Z","size":208,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-16T21:23:10.300Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easingthemes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-13T11:43:44.000Z","updated_at":"2015-09-13T11:58:34.000Z","dependencies_parsed_at":"2023-03-02T17:00:18.194Z","dependency_job_id":null,"html_url":"https://github.com/easingthemes/simple-nodejs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easingthemes%2Fsimple-nodejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easingthemes%2Fsimple-nodejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easingthemes%2Fsimple-nodejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easingthemes%2Fsimple-nodejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easingthemes","download_url":"https://codeload.github.com/easingthemes/simple-nodejs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245224582,"owners_count":20580367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T20:07:00.275Z","updated_at":"2025-03-24T07:16:19.498Z","avatar_url":"https://github.com/easingthemes.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## If you want to try it\nStart mongodb\n```\nmongod\n```\nstart project\n```\ngit clone https://github.com/easingthemes/restapi.git\ncd restapi\nnpm install\ngrunt serve\n```\n## If you want to learn\nFollow this readme and build your app from scratch.\n\nIf you use Grunt and Node modules for front-end, but you never tried server side javaScript, this tutorial is for you.\n\nApp is based on Yeoman generator angular-fullstack, but simplified a lot, and without Angular :). This is great intro for diving deeper in Angular and MEAN stack. \n\nActually this project helped me alot to finally understand some aspects of back-end development, and to separate Angular from Node.\n## Tools list\nnodejs, mongodb, grunt\n\n## Scafold project directories and files\n```\nserver/\n\tserver.js\n\troutes.js\n\tapi/\n\nclient/\n\tindex.html\n\tjs/\n\t\tapp.js\n\tlib/\n\t\tjquery.js\n```\n\nInclude app.js and jquery.js in index.html. Write down some text on the page.\n```\nclient/\n  index.html\n```\n`\u003ch1\u003eHello API\u003c/h1\u003e`\n\n## Install extensions\n####1. Create `project.json` file\n\n`npm init`\n\n####1. Create `Gruntfile.js` file\n\nGruntfile.js\n\n####2. Install node modules\n\n`npm install express mongoose body-parser lodash --save`\n\n####3. Install Dev modules for Grunt tasks\n\n`npm install grunt-contrib-watch grunt-express-server grunt-open --save-dev` \n\n\n## SERVER: express server configuration\n\n####1. Configure server\nfile: `server/server.js`\nInclude modules and define basic variables\n```\nvar express = require(\"express\"),\n    server = express(),\n    hostname = 'localhost',\n    port = 3000;\n```\n\nNow use them:\n\n```\nserver.use(express.static(__dirname + '/../app'));\nserver.listen(port, hostname);\nconsole.log(\"Server listening: http://\" + hostname + \":\" + port);\n```\n\n####2. Create GRUNT tasks for express server\n\n```\nmodule.exports = function(grunt) {\n\n  grunt.loadNpmTasks('grunt-contrib-watch');\n  grunt.loadNpmTasks('grunt-express-server');\n  grunt.loadNpmTasks('grunt-open');\n\n  grunt.initConfig({\n    watch: {\n      express: {\n        files:  [ '**/*.js' ],\n        tasks:  [ 'express:dev' ],\n        options: {\n          spawn: false\n        }\n      }\n    },\n    express: {\n      options: {\n        port: 3000\n      },\n      dev: {\n        options: {\n          script: 'server/server.js',\n          debug: true\n        }\n      }\n    },\n    open: {\n      dev: {\n        path: 'http://localhost:\u003c%= express.options.port%\u003e'\n      }\n    }\n\n  });\n\n  grunt.registerTask('serve', [ 'express:dev', 'open:dev', 'watch' ])\n\n};\n```\n\n####3. Test express server\n`grunt serve`\n\nBrowser should open configured location and you should see `hello api` page.\nThere should also be log in the terminal:\n`Server: Express listening: http://localhost:3000`\n\n## DATABASE: MongoDB configuration\n\n####1. Configure mongoose for MongoDB\n\n```\nserver/\n  server.js\n```\nStop server first `CTRL + C`\nInclude new modules\n\n```\nvar express = require(\"express\"),\n\tmongoose = require('mongoose'),\n\tbodyParser = require('body-parser'),\n\t...\n```\nWe need `mongoose` for `mongodb` manipulation and `body-parser` for sending and receiving JSON data.\n\nSo let's use them:\n\n```\napp.use(express.static(__dirname + '/../app'));\napp.use(bodyParser.json());\n...\n```\nMongoose connect\n```\nmongoose.connect('mongodb://localhost/simple', function(err) {\n    if(err) {\n        console.log('connection error', err);\n    } else {\n        console.log('connection successful');\n    }\n});\n```\n####2. Start `mongod` process\n`mongod`\nOn Windows just doubleclick `mongod.exe`\n####3. Test DB connection\nStart server again\n`grunt serve`\nThere should be new log\n`Database: MongoDB connection successful`\n\n## API Routes\n####1. Create folder for your API\n```\nserver/\n\tapi/\n\t\titem/\n```\n####2. MODEL: Create DataBase Schema\n```\nitem/\n  item.model.js\n```\nSchema types: http://mongoosejs.com/docs/schematypes.html\n```\nvar mongoose = require('mongoose'),\n    Schema = mongoose.Schema;\n\nvar ItemSchema = new Schema({\n  title: String,\n  date: Date\n});\n\nmodule.exports = mongoose.model('Item', ItemSchema);\n```\n####3. CONTROLLER: Create functions for DATABASE manipulation - CRUD: Create Read Update Delete\n```\nitem/\n  item.controller.js\n```\n```\n// Import model\nvar Item = require('./item.model');\n// READ: Get list of Items\nexports.index = function(req, res) {\n  Item.find(function (err, items) {\n    if(err) { return handleError(res, err); }\n    return res.status(200).json(items);\n  });\n};\n```\n####4. ROUTES: Define API router\n```\nitem/\n  index.js\n```\n```\n// Import extensions\nvar express = require('express'),\n  controller = require('./item.controller');\n// Define router\nvar router = express.Router();\n// Define routes\nrouter.get('/', controller.index);\n\n// Export module\nmodule.exports = router;\n```\n####5. ROUTES: Create server routes\n```\nserver/\n  routes.js\n```\n```\nmodule.exports = function(server) {\n  server.use('/api/items', require('./api/item'));\n  // All other routes should redirect to the index.html\n  server.route('/*')\n    .get(function(req, res) {\n      res.sendfile('app/index.html');\n  });\n};\n```\n####6. Test API routes\n`http://localhost:3000/api/items`\nYou should se empty array, since DB is empty.\n`[]`\n\n## CRUD - Create Read Update Delete\n \n 1. CONTROLLER: Create functions for DB manipulation - CRUD\n 2. ROUTER: Create API router\n\n#### CONTROLLER: Create functions for DB manipulation - CRUD\n\nWe need `body-parser` mongoose module to pars JSON. Add it to `server.js`\n```\nserver/\n  server.js\n```\n```\nvar express = require(\"express\"),\n  mongoose = require('mongoose'),\n  bodyParser = require('body-parser'),\n    server = express(),\n    hostname = 'localhost',\n    port = 3000; \n\nserver.use(express.static(__dirname + '/../client'));\nserver.use(bodyParser.json());\n...\n```\n```\nitem/\n  item.controller.js\n```\n```\n// Get list of Items\nexports.index = function(req, res) {\n  Item.find(function (err, items) {\n    if(err) { return handleError(res, err); }\n    return res.status(200).json(items);\n  });\n};\n// Get a single item\nexports.show = function(req, res) {\n  Item.findById(req.params.id, function (err, item) {\n    if(err) { return handleError(res, err); }\n    if(!item) { return res.sendStatus(404); }\n    return res.json(item);\n  });\n};\n//Creates a new item in the DB.\nexports.create = function(req, res) {\n  Item.create(req.body, function(err, item) {\n    if(err) { return handleError(res, err); }\n  return res.status(201).json(item);\n  });\n};\n// Updates an existing item in the DB.\nexports.update = function(req, res) {\n  if(req.body._id) { delete req.body._id; }\n  Item.findById(req.params.id, function (err, item) {\n    if (err) { return handleError(res, err); }\n    if(!item) { return res.send(404); }\n    var updated = _.merge(item, req.body);\n    updated.save(function (err) {\n      if (err) { return handleError(res, err); }\n      return res.json(200, item);\n    });\n  });\n};\n// Deletes a item from the DB.\nexports.delete = function(req, res) {\n  Item.findById(req.params.id, function (err, item) {\n    if(err) { return handleError(res, err); }\n    if(!item) { return res.sendStatus(404); }\n    item.remove(function(err) {\n      if(err) { return handleError(res, err); }\n      return res.sendStatus(204);\n    });\n  });\n};\n```\n#### ROUTER: Create API router\n```\nrouter.get('/', controller.index);\nrouter.get('/:id', controller.show);\nrouter.post('/', controller.create);\nrouter.put('/:id', controller.update);\nrouter.patch('/:id', controller.update);\nrouter.delete('/:id', controller.delete);\n```\n\n## CLIENT: use created CRUD functions from frontend\n####1. For some methods we need `lodash` module\n`npm install lodash --save`\nAdd it to \n```\nitem/\n  item.controller.js\n```\n```\nvar Item = require('./item.model');\nvar _ = require('lodash');\n```\n####2. Create DOM\n```\nclient/\n  index.html\n```\n```\n\u003ch1\u003ehello api\u003c/h1\u003e\n\u003cul\u003e\u003c/ul\u003e\n\u003cinput type=\"text\" placeholder=\"Input Item Title\"\u003e\n\u003cbutton\u003eCreate item\u003c/button\u003e\n\u003col\u003e\u003c/ol\u003e\n```\n####3. Create javaScript functions\n```\nclient/\n  js/\n    app.js\n```\n```\napp = {\n  init: function(){\n\n    app.showPosts();\n\n    $(document).on('click', 'button', function(event) {\n      event.preventDefault();\n      var itemTitle = $('input').val();\n      var jsonItem = JSON.stringify({title: itemTitle});\n      app.createPost(jsonItem);\n    });\n    $(document).on('click', 'a', function(event) {\n      event.preventDefault();\n      app.deletePost($(this).parent().attr('id'));\n    });\n    $('ul').on('click', 'li', function(event) {\n      app.showPost($(this).attr('id'));\n    });\n    $(document).on('click', 'span', function(event) {\n      var newTitle = $(this).siblings('p').text();\n      var jsonItem = JSON.stringify({title: newTitle});\n      app.updatePost($(this).parent().data('id'), jsonItem);\n    });\n  },\n  showPosts: function(){\n    //READ: get all items from API uri\n    $.get('/api/items', function(data) {\n      $.each(data, function(index, val) {\n        $('\u003cli id=\"'+val._id+'\"\u003e\u003cp\u003e'+val.title+'\u003c/p\u003e \u003ca href=\"\"\u003edelete\u003c/a\u003e\u003c/li\u003e').appendTo('ul');\n      });\n    });\n  },\n  showPost: function(itemId){\n    //GET: get single item from API uri\n    $.get('/api/items/'+itemId, function(data) {\n      $('\u003cli data-id=\"'+data._id+'\"  contenteditable=\"true\"\u003e\u003cp\u003e'+data.title+'\u003c/p\u003e \u003cspan\u003eedit\u003c/span\u003e\u003c/li\u003e').appendTo('ol');\n    }); \n  },\n  createPost: function(data){\n    //CREATE: create new item\n    $.ajax({\n      url: '/api/items',\n      type: 'POST',\n      contentType: 'application/json',\n      dataType: 'json',\n      data: data\n    })\n    .done(function(data) {\n      $('\u003cli id=\"'+data._id+'\"\u003e\u003cp\u003e'+data.title+'\u003cp\u003e \u003ca href=\"\"\u003edelete\u003c/a\u003e\u003c/li\u003e').appendTo('ul');\n    });\n  },\n  updatePost: function(itemId, newData){\n    //UPDATE: update item\n    $.ajax({\n      url: '/api/items/'+itemId,\n      type: 'PUT',\n      contentType: 'application/json',\n      dataType: 'json',\n      data: newData\n    })\n    .done(function(data) {\n      console.log(data._id+' - '+data.title);\n      $('#'+data._id+' p').text(data.title);\n    });\n  },\n  deletePost: function(itemId){\n    //DELETE: delete item\n    $.ajax({\n      url: '/api/items/'+itemId,\n      type: 'DELETE'\n    });\n    var itemElement = document.getElementById(itemId);\n    itemElement.parentNode.removeChild(itemElement);\n  }\n}\njQuery(document).ready(function($) {\n  app.init();\n});\n```\n#### DONE: \n*Starring*: nodejs with express, mongodb with mongoose\n\n*Also Starring**: Grunt\n\n*Thanks to*: body-parser, lodash, grunt-contrib-watch, grunt-express-server and grunt-open\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasingthemes%2Fsimple-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasingthemes%2Fsimple-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasingthemes%2Fsimple-nodejs/lists"}