From 0a6747f2d8b35bae38a21c87262bae8b61497a26 Mon Sep 17 00:00:00 2001 From: System Date: Sat, 18 Feb 2017 18:43:34 +0000 Subject: [PATCH] Initial commit from Gomix. --- .hyperdev-assets | 51 ++++++++ README.md | 4 +- myApp.js | 280 +++++++++++++++++++++++++++++++++++++++ package.json | 26 ++++ server.js | 331 +++++++++++++++++++++++++++++++++++++++++++++++ views/index.html | 47 +++++++ 6 files changed, 737 insertions(+), 2 deletions(-) create mode 100644 .hyperdev-assets create mode 100644 myApp.js create mode 100644 package.json create mode 100644 server.js create mode 100644 views/index.html diff --git a/.hyperdev-assets b/.hyperdev-assets new file mode 100644 index 0000000..7ae2374 --- /dev/null +++ b/.hyperdev-assets @@ -0,0 +1,51 @@ +{"name":"drag-in-files-copy.svg","date":"2016-03-16T18:27:31.021Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files-copy.svg","type":"image/svg+xml","size":6229,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files-copy.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"tkviVwlaQ2RryM4r"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:21:25.984Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"Pr0LH5dpGcRJ2QSU"} +{"name":"click-for-details.svg","date":"2016-03-16T18:21:23.511Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"nuMndaSEzn2KoNFG"} +{"name":"use-url.svg","date":"2016-03-16T18:21:20.130Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"LiyD5Lxg8FrmZlhz"} +{"name":"click-for-details.svg","date":"2016-03-16T18:20:57.943Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"04MB8gA2GPoSJ7pp"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:20:56.379Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"q8Au1vYvVFpuGd5b"} +{"name":"use-url.svg","date":"2016-03-16T18:20:52.651Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"9FiKvjvvr4C3oG0i"} +{"name":"1.svg","date":"2016-03-16T18:18:11.204Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F1.svg","type":"image/svg+xml","size":20524,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F1.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"MR02bReHwXODf2iH"} +{"name":"2.svg","date":"2016-03-16T18:18:09.776Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F2.svg","type":"image/svg+xml","size":6597,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F2.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"Q5gjW3biIe5ubDSw"} +{"name":"3.svg","date":"2016-03-16T18:18:08.145Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F3.svg","type":"image/svg+xml","size":6856,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F3.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"ZtH2QDmOOe11lCXh"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:15:33.737Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"5ZhCFJBZeljgrOsm"} +{"name":"click-for-details.svg","date":"2016-03-16T18:15:31.732Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"j9DYGSrBdfoh5Qgf"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:13:11.062Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"xs11lHNV40rcZiOr"} +{"name":"click-for-details.svg","date":"2016-03-16T18:13:07.869Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6397,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"oDrtrMLQDzHj3fCi"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:12:09.577Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"QZQEhdAJwQlN15xh"} +{"name":"click-for-details.svg","date":"2016-03-16T18:12:06.958Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6395,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"4DsIsyOkpGM5vhnm"} +{"name":"use-url.svg","date":"2016-03-16T18:12:02.187Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"2D0DVLCP7wUxzaXm"} +{"name":"click-for-details.svg","date":"2016-03-16T18:11:49.564Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6395,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"ellCYXezSjscGSrr"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:11:44.256Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"96WPtGmfDbGjk1Cq"} +{"name":"drag-in-files.svg","date":"2016-03-16T18:11:25.392Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"w2iCDrwXU3boaMb0"} +{"uuid":"w2iCDrwXU3boaMb0","deleted":true} +{"uuid":"ellCYXezSjscGSrr","deleted":true} +{"uuid":"96WPtGmfDbGjk1Cq","deleted":true} +{"uuid":"4DsIsyOkpGM5vhnm","deleted":true} +{"uuid":"QZQEhdAJwQlN15xh","deleted":true} +{"uuid":"oDrtrMLQDzHj3fCi","deleted":true} +{"uuid":"xs11lHNV40rcZiOr","deleted":true} +{"uuid":"5ZhCFJBZeljgrOsm","deleted":true} +{"uuid":"j9DYGSrBdfoh5Qgf","deleted":true} +{"uuid":"2D0DVLCP7wUxzaXm","deleted":true} +{"uuid":"04MB8gA2GPoSJ7pp","deleted":true} +{"uuid":"q8Au1vYvVFpuGd5b","deleted":true} +{"uuid":"MR02bReHwXODf2iH","deleted":true} +{"uuid":"9FiKvjvvr4C3oG0i","deleted":true} +{"uuid":"ZtH2QDmOOe11lCXh","deleted":true} +{"uuid":"Q5gjW3biIe5ubDSw","deleted":true} +{"uuid":"Pr0LH5dpGcRJ2QSU","deleted":true} +{"uuid":"tkviVwlaQ2RryM4r","deleted":true} +{"uuid":"LiyD5Lxg8FrmZlhz","deleted":true} +{"uuid":"nuMndaSEzn2KoNFG","deleted":true} +{"name":"use-url.svg","date":"2016-03-29T18:22:42.337Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":12848,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"BPzdWy4z8l1Yn4EQ"} +{"name":"drag-in-files.svg","date":"2016-03-29T18:22:44.084Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"VQVhKMzbgQcBopQk"} +{"uuid":"BPzdWy4z8l1Yn4EQ","deleted":true} +{"uuid":"VQVhKMzbgQcBopQk","deleted":true} +{"name":"click-for-details.svg","date":"2016-03-29T18:22:55.141Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":12623,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"QTRGE6XDqUiSoYO9"} +{"name":"drag-in-files.svg","date":"2016-03-29T18:22:57.596Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"RS7rnVaX9eGP4Lri"} +{"uuid":"RS7rnVaX9eGP4Lri","deleted":true} +{"uuid":"QTRGE6XDqUiSoYO9","deleted":true} +{"name":"drag-in-files.svg","date":"2016-03-29T18:23:08.746Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"fxoJRXwNdZeThuNz"} +{"name":"click-for-details.svg","date":"2016-03-29T18:23:10.422Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":12623,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"Lp2si7Cpft2ktNM4"} +{"name":"use-url.svg","date":"2016-03-29T18:23:12.439Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":12848,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"EjI8Y9wdZ9DEXI17"} diff --git a/README.md b/README.md index ef3caeb..e131c57 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# boilerplate-mongomongoose -A boilerplate for the freeCodeCamp curriculum. +FCC Mongo & Mongoose Challenges +=============================== diff --git a/myApp.js b/myApp.js new file mode 100644 index 0000000..8238721 --- /dev/null +++ b/myApp.js @@ -0,0 +1,280 @@ +/********************************************** +* 3. FCC Mongo & Mongoose Challenges +* ================================== +***********************************************/ + +/** # MONGOOSE SETUP # +/* ================== */ + +/** 1) Install & Set up mongoose */ + +// Add `mongodb` and `mongoose` to the project's `package.json`. Then require +// `mongoose`. Store your **mLab** database URI in the private `.env` file +// as `MONGO_URI`. Connect to the database using `mongoose.connect()` + + +/** # SCHEMAS and MODELS # +/* ====================== */ + +/** 2) Create a 'Person' Model */ + +// First of all we need a **Schema**. Each schema maps to a MongoDB collection +// and defines the shape of the documents within that collection. Schemas are +// building block for Models. They can be nested to create complex models, +// but in this case we'll keep things simple. A model allows you to create +// instances of your objects, called **documents**. + +// Create a person having this prototype : + +// - Person Prototype - +// -------------------- +// name : string [required] +// age : number +// favoriteFoods : array of strings (*) + +// Use the mongoose basic *schema types*. If you want you can also add more +// fields, use simple validators like `required` or `unique`, and set +// `default` values. See the [mongoose docs](http://mongoosejs.com/docs/guide.html). + +// + +var Person /* = */ + +// **Note**: GoMix is a real server, and in real servers interactions with +// the db are placed in handler functions, to be called when some event happens +// (e.g. someone hits an endpoint on your API). We'll follow the same approach +// in these exercises. The `done()` function is a callback that tells us that +// we can proceed after completing an asynchronous operation such as inserting, +// searching, updating or deleting. It's following the Node convention and +// should be called as `done(null, data)` on success, or `done(err)` on error. +// **Warning** - When interacting with remote services, **errors may occur** ! + +// - Example - +// var someFunc = function(done) { +// ... do something (risky) ... +// if(error) return done(error); +// done(null, result); +// }; + +/** # [C]RUD part I - CREATE # +/* ========================== */ + +/** 3) Create and Save a Person */ + +// Create a `document` instance using the `Person` constructor you build before. +// Pass to the constructor an object having the fields `name`, `age`, +// and `favoriteFoods`. Their types must be conformant to the ones in +// the Person `Schema`. Then call the method `document.save()` on the returned +// document instance, passing to it a callback using the Node convention. +// This is a common pattern, all the **CRUD** methods take a callback +// function like this as the last argument. + +// - Example - +// ... +// person.save(function(err, data) { +// ...do your stuff here... +// }); + +var createAndSavePerson = function(done) { + + done(null /*, data*/); + +}; + +/** 4) Create many People with `Model.create()` */ + +// Sometimes you need to create many Instances of your Models, +// e.g. when seeding a database with initial data. `Model.create()` +// takes an array of objects like [{name: 'John', ...}, {...}, ...], +// as the 1st argument, and saves them all in the db. +// Create many people using `Model.create()`, using the function argument +// 'arrayOfPeople'. + +var createManyPeople = function(arrayOfPeople, done) { + + done(null/*, data*/); + +}; + +/** # C[R]UD part II - READ # +/* ========================= */ + +/** 5) Use `Model.find()` */ + +// Find all the people having a given name, using `Model.find() -> [Person]` +// In its simplest usage, `Model.find()` accepts a **query** document (a JSON +// object ) as the first argument, and returns an **array** of matches. +// It supports an extremely wide range of search options. Check it in the docs. +// Use the function argument `personName` as search key. + +var findPeopleByName = function(personName, done) { + + done(null/*, data*/); + +}; + +/** 6) Use `Model.findOne()` */ + +// `Model.findOne()` behaves like `.find()`, but it returns **only one** +// document, even if there are more. It is especially useful +// when searching by properties that you have declared as unique. +// Find just one person which has a certain food in her favorites, +// using `Model.findOne() -> Person`. Use the function +// argument `food` as search key + +var findOneByFood = function(food, done) { + + done(null/*, data*/); + +}; + +/** 7) Use `Model.findById()` */ + +// When saving a document, mongodb automatically add the field `_id`, +// and set it to a unique alphanumeric key. Searching by `_id` is an +// extremely frequent operation, so `moongose` provides a dedicated +// method for it. Find the (only!!) person having a certain Id, +// using `Model.findById() -> Person`. +// Use the function argument 'personId' as search key. + +var findPersonById = function(personId, done) { + + done(null/*, data*/); + +}; + +/** # CR[U]D part III - UPDATE # +/* ============================ */ + +/** 8) Classic Update : Find, Edit then Save */ + +// In the good old days this was what you needed to do if you wanted to edit +// a document and be able to use it somehow e.g. sending it back in a server +// response. Mongoose has a dedicated updating method : `Model.update()`, +// which is directly binded to the low-level mongo driver. +// It can bulk edit many documents matching certain criteria, but it doesn't +// pass the edited document to its callback, only a 'status' message. +// Furthermore it makes validation difficult, because it just +// direcly calls the mongodb driver. + +// Find a person by Id ( use any of the above methods ) with the parameter +// `personId` as search key. Add "hamburger" to the list of her `favoriteFoods` +// (you can use Array.push()). Then - **inside the find callback** - `.save()` +// the updated `Person`. + +// [*] Hint: This may be tricky if in your `Schema` you declared +// `favoriteFoods` as an `Array` without specifying the type (i.e. `[String]`). +// In that case `favoriteFoods` defaults to `Mixed` type, and you have to +// manually mark it as edited using `document.markModified('edited-field')` +// (http://mongoosejs.com/docs/schematypes.html - #Mixed ) + +var findEditThenSave = function(personId, done) { + var foodToAdd = 'hamburger'; + + done(null/*, data*/); +}; + +/** 9) New Update : Use `findOneAndUpdate()` */ + +// Recent versions of `mongoose` have methods to simplify documents updating. +// Some more advanced features (i.e. pre/post hooks, validation) beahve +// differently with this approach, so the 'Classic' method is still useful in +// many situations. `findByIdAndUpdate()` can be used when searching by Id. +// +// Find a person by `name` and set her age to `20`. Use the function parameter +// `personName` as search key. +// +// Hint: We want you to return the **updated** document. In order to do that +// you need to pass the options document `{ new: true }` as the 3rd argument +// to `findOneAndUpdate()`. By default the method +// passes the unmodified object to its callback. + +var findAndUpdate = function(personName, done) { + var ageToSet = 20; + + done(null/*, data*/); +}; + +/** # CRU[D] part IV - DELETE # +/* =========================== */ + +/** 10) Delete one Person */ + +// Delete one person by her `_id`. You should use one of the methods +// `findByIdAndRemove()` or `findOneAndRemove()`. They are similar to the +// previous update methods. They pass the removed document to the cb. +// As usual, use the function argument `personId` as search key. + +var removeById = function(personId, done) { + + done(null/*, data*/); + +}; + +/** 11) Delete many People */ + +// `Model.remove()` is useful to delete all the documents matching given criteria. +// Delete all the people whose name is "Mary", using `Model.remove()`. +// Pass to it a query ducument with the "name" field set, and of course a callback. +// +// Note: `Model.remove()` doesn't return the removed document, but a document +// containing the outcome of the operation, and the number of items affected. +// Don't forget to pass it to the `done()` callback, since we use it in tests. + +var removeManyPeople = function(done) { + var nameToRemove = "Mary"; + + done(null/*, data*/); +}; + +/** # C[R]UD part V - More about Queries # +/* ======================================= */ + +/** 12) Chain Query helpers */ + +// If you don't pass the `callback` as the last argument to `Model.find()` +// (or to the other similar search methods introduced before), the query is +// not executed, and can even be stored in a variable for later use. +// This kind of object enables you to build up a query using chaining syntax. +// The actual db search is executed when you finally chain +// the method `.exec()`, passing your callback to it. +// There are many query helpers, here we'll use the most 'famous' ones. + +// Find people who like "burrito". Sort them alphabetically by name, +// Limit the results to two documents, and hide their age. +// Chain `.find()`, `.sort()`, `.limit()`, `.select()`, and then `.exec()`, +// passing the `done(err, data)` callback to it. + +var queryChain = function(done) { + var foodToSearch = "burrito"; + + done(null/*, data*/); +}; + +/** **Well Done !!** +/* You completed these challenges, let's go celebrate ! + */ + +/** # Further Readings... # +/* ======================= */ +// If you are eager to learn and want to go deeper, You may look at : +// * Indexes ( very important for query efficiency ), +// * Pre/Post hooks, +// * Validation, +// * Schema Virtuals and Model, Static, and Instance methods, +// * and much more in the [mongoose docs](http://mongoosejs.com/docs/) + + +//----- **DO NOT EDIT BELOW THIS LINE** ---------------------------------- + +exports.PersonModel = Person; +exports.createAndSavePerson = createAndSavePerson; +exports.findPeopleByName = findPeopleByName; +exports.findOneByFood = findOneByFood; +exports.findPersonById = findPersonById; +exports.findEditThenSave = findEditThenSave; +exports.findAndUpdate = findAndUpdate; +exports.createManyPeople = createManyPeople; +exports.removeById = removeById; +exports.removeManyPeople = removeManyPeople; +exports.queryChain = queryChain; diff --git a/package.json b/package.json new file mode 100644 index 0000000..7b0da5b --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "fcc-mongo-mongoose-challenges", + "version": "0.0.1", + "description": "A boilerplate project", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.12.4", + "body-parser": "^1.15.2" + }, + "engines": { + "node": "4.4.5" + }, + "repository": { + "type": "git", + "url": "https://hyperdev.com/#!/project/welcome-project" + }, + "keywords": [ + "node", + "hyperdev", + "express" + ], + "license": "MIT" +} \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..5ea094f --- /dev/null +++ b/server.js @@ -0,0 +1,331 @@ +/******************************************** + * DO NOT EDIT THIS FILE + * the verification process may break + *******************************************/ + +var express = require('express'); +var app = express(); +try{ + var mongoose = require('mongoose'); +} catch (e) { + console.log(e); +} +var fs = require('fs'); +var path = require('path'); +var bodyParser = require('body-parser'); +var router = express.Router(); + +var enableCORS = function(req, res, next) { + if (!process.env.DISABLE_XORIGIN) { + var allowedOrigins = ['https://marsh-glazer.gomix.me','https://narrow-plane.gomix.me', 'https://www.freecodecamp.com']; + var origin = req.headers.origin; + if(!process.env.XORIGIN_RESTRICT || allowedOrigins.indexOf(origin) > -1) { + console.log(req.method); + res.set({ + "Access-Control-Allow-Origin" : origin, + "Access-Control-Allow-Methods" : "GET, POST, OPTIONS", + "Access-Control-Allow-Headers" : "Origin, X-Requested-With, Content-Type, Accept" + }); + } + } + next(); +}; + +// global setting for safety timeouts to handle possible +// wrong callbacks that will never be called +var timeout = 10000; + +app.use(bodyParser.urlencoded({extended: 'false'})); +app.use(bodyParser.json()); + +app.get('/', function(req, res) { + res.sendFile(path.join(__dirname, 'views', 'index.html')); +}); + +router.get('/file/*?', function(req, res, next) { + if(req.params[0] === '.env') { return next({status: 401, message: 'ACCESS DENIED'}) } + fs.readFile(path.join(__dirname, req.params[0]), function(err, data){ + if(err) { return next(err) } + res.type('txt').send(data.toString()); + }); +}); + +var Person = require('./myApp.js').PersonModel; + +router.use(function(req, res, next) { + if(req.method !== 'OPTIONS' && Person.modelName !== 'Person') { + return next({message: 'Person Model is not correct'}); + } + next(); +}); + +router.post('/mongoose-model', function(req, res, next) { + // try to create a new instance based on their model + // verify it's correctly defined in some way + var p; + p = new Person(req.body); + res.json(p); +}); + +var createPerson = require('./myApp.js').createAndSavePerson; +router.get('/create-and-save-person', function(req, res, next) { + // in case of incorrect function use wait timeout then respond + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + createPerson(function(err, data) { + clearTimeout(t); + if(err) { return (next(err)); } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + Person.findById(data._id, function(err, pers) { + if(err) { return (next(err)); } + res.json(pers); + pers.remove(); + }); + }); +}); + +var createPeople = require('./myApp.js').createManyPeople; +router.post('/create-many-people', function(req, res, next) { + Person.remove({}, function(err) { + if(err) { return (next(err)); } + // in case of incorrect function use wait timeout then respond + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + createPeople(req.body, function(err, data) { + clearTimeout(t); + if(err) { return (next(err)); } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + Person.find({}, function(err, pers){ + if(err) { return (next(err)); } + res.json(pers); + Person.remove().exec(); + }); + }); + }); +}); + +var findByName = require('./myApp.js').findPeopleByName; +router.post('/find-all-by-name', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + Person.create(req.body, function(err, pers) { + if(err) { return next(err) } + findByName(pers.name, function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + res.json(data); + Person.remove().exec(); + }); + }); +}); + +var findByFood = require('./myApp.js').findOneByFood; +router.post('/find-one-by-food', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + var p = new Person(req.body); + p.save(function(err, pers) { + if(err) { return next(err) } + findByFood(pers.favoriteFoods[0], function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + res.json(data); + p.remove(); + }); + }); +}); + +var findById = require('./myApp.js').findPersonById; +router.get('/find-by-id', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + var p = new Person({name: 'test', age: 0, favoriteFoods: ['none']}); + p.save(function(err, pers) { + if(err) { return next(err) } + findById(pers._id, function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + res.json(data); + p.remove(); + }); + }); +}); + +var findEdit = require('./myApp.js').findEditThenSave; +router.post('/find-edit-save', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + var p = new Person(req.body); + p.save(function(err, pers) { + if(err) { return next(err) } + try { + findEdit(pers._id, function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + res.json(data); + p.remove(); + }); + } catch (e) { + console.log(e); + return next(e); + } + }); +}); + +var update = require('./myApp.js').findAndUpdate; +router.post('/find-one-update', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + var p = new Person(req.body); + p.save(function(err, pers) { + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + try { + update(pers.name, function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + res.json(data); + p.remove(); + }); + } catch (e) { + console.log(e); + return next(e); + } + }); +}); + +var removeOne = require('./myApp.js').removeById; +router.post('/remove-one-person', function(req, res, next) { + Person.remove({}, function(err) { + if(err) if(err) { return next(err) } + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + var p = new Person(req.body); + p.save(function(err, pers) { + if(err) { return next(err) } + try { + removeOne(pers._id, function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + console.log(data) + Person.count(function(err, cnt) { + if(err) { return next(err) } + data = data.toObject(); + data.count = cnt; + console.log(data) + res.json(data); + }) + }); + } catch (e) { + console.log(e); + return next(e); + } + }); + }); +}); + +var removeMany = require('./myApp.js').removeManyPeople; +router.post('/remove-many-people', function(req, res, next) { + console.log(req.body); + Person.remove({}, function(err) { + if(err) if(err) { return next(err) } + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + Person.create(req.body, function(err, pers) { + if(err) { return next(err) } + try { + removeMany(function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + Person.count(function(err, cnt) { + if(err) { return next(err) } + data = JSON.parse(data); + data.count = cnt; + res.json(data); + }) + }); + } catch (e) { + console.log(e); + return next(e); + } + }); + }) +}); + +var chain = require('./myApp.js').queryChain; +router.post('/query-tools', function(req, res, next) { + var t = setTimeout(() => { next({message: 'timeout'}) }, timeout); + Person.remove({}, function(err) { + if(err) if(err) { return next(err) } + Person.create(req.body, function(err, pers) { + if(err) { return next(err) } + if(!data) { + console.log('Missing `done()` argument'); + return next({message: 'Missing callback argument'}); + } + try { + chain(function(err, data) { + clearTimeout(t); + if(err) { return next(err) } + res.json(data); + }); + } catch (e) { + console.log(e); + return next(e); + } + }); + }) +}); + +app.use('/_api', enableCORS, router); + +// Error handler +app.use(function(err, req, res, next) { + if(err) { + res.status(err.status || 500) + .type('txt') + .send(err.message || 'SERVER ERROR'); + } +}); + +// Unmatched routes handler +app.use(function(req, res){ + if(req.method.toLowerCase() === 'options') { + res.end(); + } else { + res.status(404).type('txt').send('Not Found'); + } +}) + +var listener = app.listen(process.env.PORT || 3000 , function () { + console.log('Your app is listening on port ' + listener.address().port); +}); + +/******************************************** + * DO NOT EDIT THIS FILE + * the verification process may break + *******************************************/ diff --git a/views/index.html b/views/index.html new file mode 100644 index 0000000..221a551 --- /dev/null +++ b/views/index.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + Welcome to HyperDev! + + + + + + + + + +
+

+ 3. FCC Mongo & Mongoose Challenges +

+
+ +
+ +
+ + + + +