javascript MongoDB代写: Web 2.0 Application Development (EG3779)

 

 

 

Course :

 

Diploma in Multimedia & Infocomm Technology (EGDF15)

Module : Web 2.0 Application Development (EG3779)

 

 

Laboratory :

 

6. MongoDB II

Objectives : The objective of this lab is to learn how to design and develop a web application using Node.js technologies and MongoDB. You will also learn how to design a proper code structure which supports the MVC framework.
Software(s) : Brackets, Chrome
Instructions : You are highly encouraged to refer to Mongoose Documentation (http://mongoosejs.com/docs/guide.html) to understand about Mongoose API.

 

 

 

Preparation Work

P1.

 

Spend 10min to understand JavaScript Promises. We will use a lot in this lab assignment.

P2.      Download Lab6.zip from Blackboard à Lab 6 à Lab6.zip. It contains a modified version of the Lab4Ex2.

P3. Unzip the folder and spend few minutes understanding the code structure.

The internal <script> tag for all the HTML files have been shifted to external JS files.  In routes.js, notice the use of express routes to handle the HTTP POST and GET calls. It is useful when you want to use duplicate route name for different HTTP requests.

 

Exercise 1 – Connection to Database

 

  1. Open js and add the following codes to the top of the file.

 

const mongoose = require(‘mongoose’);

const schema = mongoose.Schema;

var eventSchema = {};

var EventModel;

 

The purpose of the schema object is to allow developers to create the schema for the mongoose model to be stored in the MongoDB collection.

 

EventModel is the model representation of the collection in MongoDB.

 

  1. Implement the connect

 

return mongoose.connect(‘mongodb://localhost:27017/’, { dbName: ‘eventManagement’ });

 

This command returns a Promise, which will be handled by the server when connecting to the database.

  1. Implement the initialize

eventSchema = schema({

name: String,

description: String,

start: {

date: Date,

time: String

},

end: {

date: Date,

time: String

}

});

var connection = mongoose.connection;

EventModel = connection.model(‘Event’, eventSchema);

 

 

  1. Add a new required statement to js.

const db = require(‘./js/datastorage.js’);

 

  1. Add new functions to js.

 

var server = {

 

/*existing codes (do not remove them). Add the following two functions.*/

 

connectToDB: () => {

Handles the resolve function from database connection’s Promise returned from step 1a.

return new Promise((resolve, reject) => {

db.connect()

.then(

() => {

db.initialize();

resolve(“Connected to MongoDB”);

}

Handles the reject function from database connection’s Promise returned from step 1a.

)

.catch(

(reason) => {

reject(reason);

}

);

});

},

getDB: () => {

return db;

}

}

 

 

Handles the resolve and reject functions from server’s connectToDB() Promise returned from step 3. Note the use of functions as parameters in this example.
  • Add the following lines in js.

 

server.connectToDB()

.then(dbConnectionSuccess)

.catch(errorHandler);

 

function dbConnectionSuccess(message) {

console.log(message);

const eventManagement = require(‘./js/eventManagement.js’);

io.on(‘connection’, (socket) => {

//to send the events and handle io topics

});

}

 

function errorHandler(err) {

console.log(err);

}

 

Start MongoDB service.

Start your node application.

Ensure that the server is started and MongoDB is connected. If it is not, stop here and ask for help!

 

Figure 1: Sequence diagram for connecting to database

 

Exercise 2 – Create events

 

  1. Open js and implement the addEvent function.

var newEvent = new EventModel({

name: name,

description: description,

start: {

date: startDate,

time: startTime

},

end: {

date: endDate,

time: endTime

}

});

return newEvent.save();

 

This function returns a Promise, which contains the newly added event if resolved, or errors if rejected.

 

  1. Open js and implement the addEvent function.

return new Promise((resolve, reject) => {

db.addEvent(newEvent.name, newEvent.description,

newEvent.startDate, newEvent.startTime,

newEvent.endDate, newEvent.endTime)

.then(

(data) => {

resolve(data);

}

)

.catch(

(err) => {

reject(err);

}

);

});

 

  1. Open js and edit the post handler for the ‘/events’ route.
Similar to Lab4, with the extra handling for Promise’s resolve and reject callback functions

 

var data = req.body;

eventManagement.addEvent(data)

.then(

() => {

res.status(200).send(“Event added successfully!”);

})

.catch(

(err) => {

res.status(500).send(err);

}

);

 

 

  1. Open js and add the following codes inside the button click listener.

It was initially the $.post(…) codes in Lab4Ex2.

$.ajax(

{

url: ‘/events’,

method: ‘post’,

data: event

}

).done((data) => {

$(“.statusMessage”).text(data);

}).fail((err) => {

$(“.statusMessage”).text(err.responseText);

}

 

 

Relaunch your application and test the creation of events. Ensure that you can see your new events in MongoDB Compass.

 

Figure 2: Sequence diagram of adding events

 

The sequence diagrams for update and delete events will be similar as above.

 

 

Exercise 3 – Retrieve events

 

  1. Open js. These functions return Promises.

 

  1. Implement the getAllEvents

 

return EventModel.find({}).exec();

 

  1. Implement the getEvent

 

return EventModel.findById(id).exec();

 

  1. Open js.

 

  1. Implement the getEvents

 

return new Promise((resolve, reject) => {

db.getAllEvents()

.then(

(data) => {

resolve(data);

}

)

.catch(

(err) => {

reject(err);

}

);

});

 

 

  1. Implement the getEvent

 

return new Promise((resolve, reject) => {

db.getEvent(id)

.then(

(data) => {

resolve(data);

}

)

.catch(

(err) => {

reject(err);

}

);

});

 

  1. Open js and edit the io connection function in dbConnectionSuccess function.

io.on(‘connection’, (socket) => {

eventManagement.getEvents().then(emitAllEvents,errorHandler);

 

socket.on(“fetchEvent”,(eventId)=>{

eventManagement.getEvent(eventId).then(emitEvent,errorHandler);

});

});

 

 

  1. Add the following functions to js.

 

function emitAllEvents(data) {

io.emit(‘allEvents’, data);

}

 

function emitEvent(data) {

io.emit(‘event’, data);

}

 

Relaunch your application and test the retrieval of events. Ensure that you can see the events in the home page.

 

  1. Open js and add a hyperlink to the event name. The “/edit” route has already been handled in the routes.js.

 

$(“.events”).append(“<h2><a href=’/edit’ id='”+event._id+“‘ class=’eventLink’>“+event.name+”</a></h2>”);

 

  1. Add the following codes after the $.each {..} block

 

$(“.eventLink”).on(‘click’,(evt)=>{

var eventId = $(evt.target).attr(‘id’);

sessionStorage.setItem(“eventId”,eventId);

});

 

Explanation of the above codes – When the hyperlink is clicked, the clicked target’s element is retrieved using $(evt.target). This is an in-built property of JavaScript/jQuery. The application will store the eventId in the session and move on to the next page (“editEvent.html”).

 

  1. Open js and add the following codes in the ready function.

var socket = io.connect(‘http://localhost:3000’);

var eventId = sessionStorage.getItem(“eventId”);

 

//ask server to fetch event using the id

socket.emit(“fetchEvent“, eventId);

 

socket.on(“event“,(data)=>{

document.title=data.name;

var start = new Date(data.start.date);

var end = new Date(data.end.date);

$(‘#name’).val(data.name);

$(‘#description’).val(data.description);

$(‘#startDate’).val(start.toISOString().slice(0,10));

$(‘#startTime’).val(data.start.time);

$(‘#endDate’).val(end.toISOString().slice(0,10));

$(‘#endTime’).val(data.end.time);

})

 

Relaunch your application and test the retrieval of single event. Ensure that you can click the hyperlink and redirect you to the edit event page, with the edit form filled up.

 

 

Exercise 4 – Update events

 

  1. Open js and add the following codes for the edit button handler.

 

$(“.editEventBtn”).on(‘click’, () => {

var event = {

id: eventId,

name: $(“#name”).val(),

description: $(“#description”).val(),

startDate: $(“#startDate”).val(),

startTime: $(“#startTime”).val(),

endDate: $(“#endDate”).val(),

endTime: $(“#endTime”).val()

};

$.ajax(

{

url: ‘/events’,

method: ‘put’,

data: event

}

).done((data)=>{

$(“.statusMessage”).text(data);

}).fail((err)=>{

$(“.statusMessage”).text(err.responseText);

});

})

 

Now you need to handle the HTTP PUT route on the server.

 

 

  1. Open js and add the following codes after the HTTP POST handler for (‘/events).

 

externalRoutes.route(‘/events’)

.post(/*existing codes*/)

.put((req, res) => {

var data = req.body;

eventManagement.updateEvent(data)

.then(

() => {

res.status(200).send(“Event updated successfully!”);

})

.catch(

(err) => {

res.status(500).send(err);

}

);

})

 

 

  1. Open js and implement updateEvent function.

 

return new Promise((resolve, reject) => {

db.updateEvent(updatedEvent.id, updatedEvent.name,

updatedEvent.description, updatedEvent.startDate,

updatedEvent.startTime, updatedEvent.endDate,

updatedEvent.endTime)

.then(

(data) => {

resolve(data);

}

)

.catch(

(err) => {

reject(err);

}

);

});

 

 

  1. Open js and implement updateEvent function.

 

var updatedEvent = {

name: name,

description: description,

start: {

date: startDate,

time: startTime

},

end: {

date: endDate,

time: endTime

}

};

return EventModel.findByIdAndUpdate(id, updatedEvent).exec();

 

This function returns a Promise.

 

Relaunch the application and test if you can save the event.

 

 

Exercise 5 – Delete events

 

  1. Open js and implement the deleteEvent function.

 

return EventModel.findByIdAndDelete(id).exec();

 

This function returns a Promise.

 

  1. Open js and implement the deleteEvent function.

return new Promise((resolve, reject) => {

db.deleteEvent(id)

.then(

() => {

resolve();

}

)

.catch(

(err) => {

reject(err);

}

);

})

 

  1. Open js and add the following codes after the HTTP PUT handler.

 

.delete((req, res) => {

var id = req.body.id;

eventManagement.deleteEvent(id)

.then(

() => {

res.status(200).send(“Event deleted successfully!”);

})

.catch(

(err) => {

res.status(500).send(err);

}

);

}

);

 

  1. Open js and add the following codes for the delete button handler.

 

$(“.deleteEventBtn”).on(‘click’,()=>{

$.ajax(

{

url: ‘/events’,

method: ‘delete’,

data: {id:eventId}

}

).done((data)=>{

alert(data);

window.location.href=”/”;

}).fail((err)=>{

$(“.statusMessage”).text(err.responseText);

});

});

 

Relaunch your application and test if your event can be deleted.

 

 

Exercise 6 – Search events

 

  1. Open js and add the following codes.

 

$(“.searchBtn”).on(‘click’, ()=>{

$.ajax(

{

Do a HTTP POST to /search.

The data should be a JSON object containing only one field ‘searchText’

}

).done((data)=>{

/* same codes from lines 4 – 17. */

}).fail((err)=>{

console.log(err.responseText);

});

 

  1. Open js and implement the /search route to handle the above request.

 

eventManagement.searchEvent(        )

 

Handle the Promise’s resolve and reject. You need to send the data resolved from the searchEvent’s Promise to the client.

);

 

 

 

  1. Open js and implement the searchEvent function.

 

return new Promise((resolve, reject) => {

db.searchEvent(searchText)

.then(

(data) => {

resolve(data);

}

)

.catch(

(err) => {

reject(err);

}

)

})

}

 

  1. Open js and implement the searchEvent function.

 

return EventModel.find({name: new RegExp(searchText,‘i’)}).exec();

 

Explanation of the arguments in the find function:

 

It takes in the search criteria as a JSON object. If {} is specified (see the getAllEvents()), then all documents are returned.

 

If you specify { key: value }, the documents matching the exact key : value pair will be returned.

 

But if you were to implement a search function, you will likely to prefer search by partial string. (like the SQL LIKE clause).

 

In mongoose, you can use RegExp in JavaScript to search the document based on specific regular expressions. The ‘i’ indicator as a second parameter represents case insensitivity.

 

You can also put in multiple search criteria separated by key : value pairs.

Relaunch the application and test the search function. The program will search by event name.