├── sample.env
├── .gitignore
├── .gitpod.yml
├── README.md
├── package.json
├── views
└── index.html
├── myApp.js
└── server.js
/sample.env:
--------------------------------------------------------------------------------
1 | MONGO_URI=
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | node_modules
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | image: gitpod/workspace-node-lts
2 |
3 | ports:
4 | - port: 3000
5 | onOpen: open-preview
6 | visibility: public
7 |
8 | tasks:
9 | - init: npm install
10 | command: npm run start
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MongoDB and Mongoose Challenges
2 |
3 | This is the boilerplate for the MongoDB and Mongoose lessons. Instructions for completing these lessons start at https://www.freecodecamp.org/learn/apis-and-microservices/mongodb-and-mongoose/
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fcc-mongo-mongoose-challenges",
3 | "version": "0.0.1",
4 | "description": "A boilerplate project",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "node server.js"
8 | },
9 | "dependencies": {
10 | "body-parser": "^1.15.2",
11 | "dotenv": "^8.2.0",
12 | "express": "^4.12.4",
13 | "mongoose": "^5.11.15"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/freeCodeCamp/boilerplate-mongomongoose.git"
18 | },
19 | "keywords": [
20 | "node",
21 | "mongoose",
22 | "express"
23 | ],
24 | "license": "MIT"
25 | }
26 |
--------------------------------------------------------------------------------
/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | MongoDB & Mongoose | freeCodeCamp.org
14 |
19 |
20 |
21 |
22 |
30 |
31 |
32 |
33 | MongoDB & Mongoose
34 |
35 |
36 |
--------------------------------------------------------------------------------
/myApp.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 |
4 | let Person;
5 |
6 | const createAndSavePerson = (done) => {
7 | done(null /*, data*/);
8 | };
9 |
10 | const createManyPeople = (arrayOfPeople, done) => {
11 | done(null /*, data*/);
12 | };
13 |
14 | const findPeopleByName = (personName, done) => {
15 | done(null /*, data*/);
16 | };
17 |
18 | const findOneByFood = (food, done) => {
19 | done(null /*, data*/);
20 | };
21 |
22 | const findPersonById = (personId, done) => {
23 | done(null /*, data*/);
24 | };
25 |
26 | const findEditThenSave = (personId, done) => {
27 | const foodToAdd = "hamburger";
28 |
29 | done(null /*, data*/);
30 | };
31 |
32 | const findAndUpdate = (personName, done) => {
33 | const ageToSet = 20;
34 |
35 | done(null /*, data*/);
36 | };
37 |
38 | const removeById = (personId, done) => {
39 | done(null /*, data*/);
40 | };
41 |
42 | const removeManyPeople = (done) => {
43 | const nameToRemove = "Mary";
44 |
45 | done(null /*, data*/);
46 | };
47 |
48 | const queryChain = (done) => {
49 | const foodToSearch = "burrito";
50 |
51 | done(null /*, data*/);
52 | };
53 |
54 | /** **Well Done !!**
55 | /* You completed these challenges, let's go celebrate !
56 | */
57 |
58 | //----- **DO NOT EDIT BELOW THIS LINE** ----------------------------------
59 |
60 | exports.PersonModel = Person;
61 | exports.createAndSavePerson = createAndSavePerson;
62 | exports.findPeopleByName = findPeopleByName;
63 | exports.findOneByFood = findOneByFood;
64 | exports.findPersonById = findPersonById;
65 | exports.findEditThenSave = findEditThenSave;
66 | exports.findAndUpdate = findAndUpdate;
67 | exports.createManyPeople = createManyPeople;
68 | exports.removeById = removeById;
69 | exports.removeManyPeople = removeManyPeople;
70 | exports.queryChain = queryChain;
71 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | /********************************************
2 | * DO NOT EDIT THIS FILE
3 | * the verification process may break
4 | *******************************************/
5 |
6 | const express = require("express");
7 | const app = express();
8 | let mongoose;
9 | try {
10 | mongoose = require("mongoose");
11 | } catch (e) {
12 | console.log(e);
13 | }
14 | const fs = require("fs");
15 | const path = require("path");
16 | const bodyParser = require("body-parser");
17 | const router = express.Router();
18 |
19 | const enableCORS = function (req, res, next) {
20 | if (!process.env.DISABLE_XORIGIN) {
21 | const allowedOrigins = ["https://www.freecodecamp.org"];
22 | const origin = req.headers.origin;
23 | if (!process.env.XORIGIN_RESTRICT || allowedOrigins.indexOf(origin) > -1) {
24 | console.log(req.method);
25 | res.set({
26 | "Access-Control-Allow-Origin": origin,
27 | "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
28 | "Access-Control-Allow-Headers":
29 | "Origin, X-Requested-With, Content-Type, Accept",
30 | });
31 | }
32 | }
33 | next();
34 | };
35 |
36 | // global setting for safety timeouts to handle possible
37 | // wrong callbacks that will never be called
38 | const TIMEOUT = 10000;
39 |
40 | app.use(bodyParser.urlencoded({ extended: "false" }));
41 | app.use(bodyParser.json());
42 |
43 | app.get("/", function (req, res) {
44 | res.sendFile(path.join(__dirname, "views", "index.html"));
45 | });
46 |
47 | router.get("/file/*?", function (req, res, next) {
48 | if (req.params[0] === ".env") {
49 | return next({ status: 401, message: "ACCESS DENIED" });
50 | }
51 | fs.readFile(path.join(__dirname, req.params[0]), function (err, data) {
52 | if (err) {
53 | return next(err);
54 | }
55 | res.type("txt").send(data.toString());
56 | });
57 | });
58 |
59 | router.get("/is-mongoose-ok", function (req, res) {
60 | if (mongoose) {
61 | res.json({ isMongooseOk: !!mongoose.connection.readyState });
62 | } else {
63 | res.json({ isMongooseOk: false });
64 | }
65 | });
66 |
67 | const Person = require("./myApp.js").PersonModel;
68 |
69 | router.use(function (req, res, next) {
70 | if (req.method !== "OPTIONS" && Person.modelName !== "Person") {
71 | return next({ message: "Person Model is not correct" });
72 | }
73 | next();
74 | });
75 |
76 | router.post("/mongoose-model", function (req, res, next) {
77 | // try to create a new instance based on their model
78 | // verify it's correctly defined in some way
79 | let p;
80 | p = new Person(req.body);
81 | res.json(p);
82 | });
83 |
84 | const createPerson = require("./myApp.js").createAndSavePerson;
85 | router.get("/create-and-save-person", function (req, res, next) {
86 | // in case of incorrect function use wait timeout then respond
87 | let t = setTimeout(() => {
88 | next({ message: "timeout" });
89 | }, TIMEOUT);
90 | createPerson(function (err, data) {
91 | clearTimeout(t);
92 | if (err) {
93 | return next(err);
94 | }
95 | if (!data) {
96 | console.log("Missing `done()` argument");
97 | return next({ message: "Missing callback argument" });
98 | }
99 | Person.findById(data._id, function (err, pers) {
100 | if (err) {
101 | return next(err);
102 | }
103 | res.json(pers);
104 | pers.remove();
105 | });
106 | });
107 | });
108 |
109 | const createPeople = require("./myApp.js").createManyPeople;
110 | router.post("/create-many-people", function (req, res, next) {
111 | Person.remove({}, function (err) {
112 | if (err) {
113 | return next(err);
114 | }
115 | // in case of incorrect function use wait timeout then respond
116 | let t = setTimeout(() => {
117 | next({ message: "timeout" });
118 | }, TIMEOUT);
119 | createPeople(req.body, function (err, data) {
120 | clearTimeout(t);
121 | if (err) {
122 | return next(err);
123 | }
124 | if (!data) {
125 | console.log("Missing `done()` argument");
126 | return next({ message: "Missing callback argument" });
127 | }
128 | Person.find({}, function (err, pers) {
129 | if (err) {
130 | return next(err);
131 | }
132 | res.json(pers);
133 | Person.remove().exec();
134 | });
135 | });
136 | });
137 | });
138 |
139 | const findByName = require("./myApp.js").findPeopleByName;
140 | router.post("/find-all-by-name", function (req, res, next) {
141 | let t = setTimeout(() => {
142 | next({ message: "timeout" });
143 | }, TIMEOUT);
144 | Person.create(req.body, function (err, pers) {
145 | if (err) {
146 | return next(err);
147 | }
148 | findByName(pers.name, function (err, data) {
149 | clearTimeout(t);
150 | if (err) {
151 | return next(err);
152 | }
153 | if (!data) {
154 | console.log("Missing `done()` argument");
155 | return next({ message: "Missing callback argument" });
156 | }
157 | res.json(data);
158 | Person.remove().exec();
159 | });
160 | });
161 | });
162 |
163 | const findByFood = require("./myApp.js").findOneByFood;
164 | router.post("/find-one-by-food", function (req, res, next) {
165 | let t = setTimeout(() => {
166 | next({ message: "timeout" });
167 | }, TIMEOUT);
168 | let p = new Person(req.body);
169 | p.save(function (err, pers) {
170 | if (err) {
171 | return next(err);
172 | }
173 | findByFood(pers.favoriteFoods[0], function (err, data) {
174 | clearTimeout(t);
175 | if (err) {
176 | return next(err);
177 | }
178 | if (!data) {
179 | console.log("Missing `done()` argument");
180 | return next({ message: "Missing callback argument" });
181 | }
182 | res.json(data);
183 | p.remove();
184 | });
185 | });
186 | });
187 |
188 | const findById = require("./myApp.js").findPersonById;
189 | router.get("/find-by-id", function (req, res, next) {
190 | let t = setTimeout(() => {
191 | next({ message: "timeout" });
192 | }, TIMEOUT);
193 | let p = new Person({ name: "test", age: 0, favoriteFoods: ["none"] });
194 | p.save(function (err, pers) {
195 | if (err) {
196 | return next(err);
197 | }
198 | findById(pers._id, function (err, data) {
199 | clearTimeout(t);
200 | if (err) {
201 | return next(err);
202 | }
203 | if (!data) {
204 | console.log("Missing `done()` argument");
205 | return next({ message: "Missing callback argument" });
206 | }
207 | res.json(data);
208 | p.remove();
209 | });
210 | });
211 | });
212 |
213 | const findEdit = require("./myApp.js").findEditThenSave;
214 | router.post("/find-edit-save", function (req, res, next) {
215 | let t = setTimeout(() => {
216 | next({ message: "timeout" });
217 | }, TIMEOUT);
218 | let p = new Person(req.body);
219 | p.save(function (err, pers) {
220 | if (err) {
221 | return next(err);
222 | }
223 | try {
224 | findEdit(pers._id, function (err, data) {
225 | clearTimeout(t);
226 | if (err) {
227 | return next(err);
228 | }
229 | if (!data) {
230 | console.log("Missing `done()` argument");
231 | return next({ message: "Missing callback argument" });
232 | }
233 | res.json(data);
234 | p.remove();
235 | });
236 | } catch (e) {
237 | console.log(e);
238 | return next(e);
239 | }
240 | });
241 | });
242 |
243 | const update = require("./myApp.js").findAndUpdate;
244 | router.post("/find-one-update", function (req, res, next) {
245 | let t = setTimeout(() => {
246 | next({ message: "timeout" });
247 | }, TIMEOUT);
248 | let p = new Person(req.body);
249 | p.save(function (err, pers) {
250 | if (err) {
251 | return next(err);
252 | }
253 | try {
254 | update(pers.name, function (err, data) {
255 | clearTimeout(t);
256 | if (err) {
257 | return next(err);
258 | }
259 | if (!data) {
260 | console.log("Missing `done()` argument");
261 | return next({ message: "Missing callback argument" });
262 | }
263 | res.json(data);
264 | p.remove();
265 | });
266 | } catch (e) {
267 | console.log(e);
268 | return next(e);
269 | }
270 | });
271 | });
272 |
273 | const removeOne = require("./myApp.js").removeById;
274 | router.post("/remove-one-person", function (req, res, next) {
275 | Person.remove({}, function (err) {
276 | if (err) {
277 | return next(err);
278 | }
279 | let t = setTimeout(() => {
280 | next({ message: "timeout" });
281 | }, TIMEOUT);
282 | let p = new Person(req.body);
283 | p.save(function (err, pers) {
284 | if (err) {
285 | return next(err);
286 | }
287 | try {
288 | removeOne(pers._id, function (err, data) {
289 | clearTimeout(t);
290 | if (err) {
291 | return next(err);
292 | }
293 | if (!data) {
294 | console.log("Missing `done()` argument");
295 | return next({ message: "Missing callback argument" });
296 | }
297 | console.log(data);
298 | Person.count(function (err, cnt) {
299 | if (err) {
300 | return next(err);
301 | }
302 | data = data.toObject();
303 | data.count = cnt;
304 | console.log(data);
305 | res.json(data);
306 | });
307 | });
308 | } catch (e) {
309 | console.log(e);
310 | return next(e);
311 | }
312 | });
313 | });
314 | });
315 |
316 | const removeMany = require("./myApp.js").removeManyPeople;
317 | router.post("/remove-many-people", function (req, res, next) {
318 | Person.remove({}, function (err) {
319 | if (err) {
320 | return next(err);
321 | }
322 | let t = setTimeout(() => {
323 | next({ message: "timeout" });
324 | }, TIMEOUT);
325 | Person.create(req.body, function (err, pers) {
326 | if (err) {
327 | return next(err);
328 | }
329 | try {
330 | removeMany(function (err, data) {
331 | clearTimeout(t);
332 | if (err) {
333 | return next(err);
334 | }
335 | if (!data) {
336 | console.log("Missing `done()` argument");
337 | return next({ message: "Missing callback argument" });
338 | }
339 | Person.count(function (err, cnt) {
340 | if (err) {
341 | return next(err);
342 | }
343 | if (data.ok === undefined) {
344 | // for mongoose v4
345 | try {
346 | data = JSON.parse(data);
347 | } catch (e) {
348 | console.log(e);
349 | return next(e);
350 | }
351 | }
352 | res.json({
353 | n: data.n,
354 | count: cnt,
355 | ok: data.ok,
356 | });
357 | });
358 | });
359 | } catch (e) {
360 | console.log(e);
361 | return next(e);
362 | }
363 | });
364 | });
365 | });
366 |
367 | const chain = require("./myApp.js").queryChain;
368 | router.post("/query-tools", function (req, res, next) {
369 | let t = setTimeout(() => {
370 | next({ message: "timeout" });
371 | }, TIMEOUT);
372 | Person.remove({}, function (err) {
373 | if (err) {
374 | return next(err);
375 | }
376 | Person.create(req.body, function (err, pers) {
377 | if (err) {
378 | return next(err);
379 | }
380 | try {
381 | chain(function (err, data) {
382 | clearTimeout(t);
383 | if (err) {
384 | return next(err);
385 | }
386 | if (!data) {
387 | console.log("Missing `done()` argument");
388 | return next({ message: "Missing callback argument" });
389 | }
390 | res.json(data);
391 | });
392 | } catch (e) {
393 | console.log(e);
394 | return next(e);
395 | }
396 | });
397 | });
398 | });
399 |
400 | app.use("/_api", enableCORS, router);
401 |
402 | // Error handler
403 | app.use(function (err, req, res, next) {
404 | if (err) {
405 | res
406 | .status(err.status || 500)
407 | .type("txt")
408 | .send(err.message || "SERVER ERROR");
409 | }
410 | });
411 |
412 | // Unmatched routes handler
413 | app.use(function (req, res) {
414 | if (req.method.toLowerCase() === "options") {
415 | res.end();
416 | } else {
417 | res.status(404).type("txt").send("Not Found");
418 | }
419 | });
420 |
421 | const listener = app.listen(process.env.PORT || 3000, function () {
422 | console.log("Your app is listening on port " + listener.address().port);
423 | });
424 |
425 | /********************************************
426 | * DO NOT EDIT THIS FILE
427 | * the verification process may break
428 | *******************************************/
429 |
--------------------------------------------------------------------------------