Nguyen Linh
Nguyen Linh
Bachelor of Engineering
Information Technology
2024
Degree title Bachelor of Engineering
Author(s) Linh Nguyen
Thesis title Developing an animal rescue and adoption website
Commissioned by -
Year 2024
Pages 48 pages, 3 pages of appendices
Supervisor(s) Tuomas Reijonen
ABSTRACT
The goal of this thesis was to develop a website for animal shelter organizations.
This platform allows individuals to apply for pet adoption through an application
form. Additionally, the website enables the organization to receive donations,
either as one-time contributions or monthly.
The website was developed with the use of MERN stack which consists of
MongoDB, ExpressJS, ReactJS, and NodeJS. The front-end is powered by
ReactJS, while NodeJS and ExpressJS keep the back-end connected to the
database in MongoDB. Communication between the front-end and backend
occurs via REST API, allowing for autonomous development of both the front-end
and back-end elements of the application. The theoretical background provided
deep knowledge for the implementation part.
1 INTRODUCTION ............................................................................................ 4
2 THEORY BACKGROUND .............................................................................. 5
2.1 JavaScript................................................................................................. 5
2.2 React.js .................................................................................................... 7
2.2.1 Virtual DOM ........................................................................................ 7
2.2.2 JSX ..................................................................................................... 8
2.3 Node.js ..................................................................................................... 9
2.4 Express.js ............................................................................................... 10
2.5 MongoDB ............................................................................................... 11
2.6 REST API ............................................................................................... 13
3 IMPLEMENTATION ..................................................................................... 15
3.1 Website Overview .................................................................................. 15
3.2 Back-end Implementation ....................................................................... 16
3.2.1 API planning ..................................................................................... 16
3.2.2 Server implementation...................................................................... 18
3.3 Home page ............................................................................................. 27
3.4 Register page ......................................................................................... 28
3.5 Log in page............................................................................................. 31
3.6 Adopt page ............................................................................................. 33
3.7 Animal detail page .................................................................................. 35
3.8 Adoption application form ....................................................................... 36
3.9 Donate page ........................................................................................... 38
3.10 Contact page .......................................................................................... 40
4 FUTURE DEVELOPMENT ........................................................................... 41
5 CONCLUSION ............................................................................................. 42
REFERENCES .................................................................................................... 44
LIST OF FIGURES .............................................................................................. 47
4
1 INTRODUCTION
Since the inception of the Internet in the early 1980s, the world has undergone
significant transformations. Presently, the Internet has evolved into an essential
component of people's daily lives, appearing in all fields and wielding an
undeniable influence. Concurrently, propelled by rapid technological
advancements, the desire to establish websites pervades most organizations,
enterprises, and individuals. Websites serve multifaceted purposes, not only
enabling businesses to remain abreast in the high-tech era but also bolstering
brand visibility. Serving as a visual representation of organizational information,
websites facilitate seamless user access to projects, thereby fostering user
interaction and facilitating a positive user experience.
The development of the Internet has brought about significant changes in many
different aspects of society, reshaping the way we communicate, access
information, and interact with the world, thereby creating impacts. to social norms
and behavior. Before there was no Internet, social issues about people, the
environment, and animals seemed to be little known by people who did not read
newspapers or listen to the radio. Now increased access to information and
greater awareness of these issues have caused a shift in perception. What we
want to talk about regarding this topic is humanity's concern for animals,
especially homeless dogs and cats. More and more non-profit organizations are
being established to support and rescue unfortunate animals, and people are
willing to lend a helping hand to these creatures. By harnessing the power of
technology to facilitate the adoption process and provide support for vulnerable
animals. Further bridging the gap between digital innovation and altruistic
endeavors, this project demonstrates the intersection of technological
advancement and humanitarian values in our connected world.
Websites provide an efficient tool for updating information about animals at care
stations quickly and accurately. This offers users a convenient and enjoyable
5
experience. The website has two roles: admin and users. The admin manages
the website by adding, updating, and deleting animals’ information. Users can
view, search for animals that they want, fill out the adoption application, and
donate through payment method (eg.PayPal).
2 THEORY BACKGROUND
2.1 JavaScript
JavaScript serves as a pivotal scripting language among the trio essential for
website development. While HTML and CSS lay the foundation and design
elements of a webpage, JavaScript empowers developers to infuse functionality
and interactivity into their creations. This dynamic language enables the
implementation of intricate web features, facilitating engaging user experiences
beyond the capabilities of HTML or CSS alone. (DeGroat, 2019)
6
2.2 React.js
Figure 2 shows the process of how React updates the user interface efficiently.
Initially, React creates a Virtual DOM, a lightweight, in-memory representation of
a component’s UI structure. When a component's state or props change, React
constructs a new Virtual DOM and reconciles it with the previous one using a
diffing algorithm to identify differences. To optimize performance, React batches
multiple updates into a single process, minimizing changes to the real DOM.
Once changes are determined, the real DOM is updated with minimal
manipulations. React also reuses components and uses unique key props for list
elements to streamline the process. Additionally, React’s state management and
Hooks system play a crucial role in identifying which components need re-
rendering, ensuring efficient and responsive UI updates. This systematic process
ensures that only the necessary changes are made, keeping the application fast
and responsive. (CHAUHAN, 2023)
2.2.2 JSX
JSX, which stands for JavaScript XML, is a syntax extension for JavaScript that
allows developers to write HTML-like code directly within JavaScript. It simplifies
the process of creating and manipulating UI elements in React applications by
combining HTML structure and JavaScript logic into a single file. JSX is used by
enclosing HTML-like syntax within curly braces {} within JavaScript code.
Figure 3 illustrates the difference between writing React code with and without
JSX. The benefits of JSX include improved readability, easier integration of UI
components with JavaScript logic, and enhanced developer productivity.
Additionally, JSX is transpiled into regular JavaScript code by tools like Babel,
making it compatible with all browsers. Overall, JSX streamlines the development
process and enhances the maintainability of React applications. (Corbeel, 2024)
2.3 Node.js
2.4 Express.js
2.5 MongoDB
MongoDB was founded in 2007 by Dwight Merriman, Eliot Horowitz, and Kevin
Ryan – the team behind DoubleClick. MongoDB is a popular open-source NoSQL
database management system designed for scalability, flexibility, and
performance. It uses a document-oriented data model, storing data in flexible,
JSON-like documents, making it ideal for handling unstructured or semi-
structured data.
Despite MongoDB’s many strengths, it also carries a few drawbacks that warrant
consideration. It limited transaction scope and hindered complex operations
across multiple data pieces. While offering ACID compliance at the document
level, MongoDB lacks full ACID compliance across collections, posing challenges
for intricate transactional requirements. Limited join capabilities compared to
relational databases necessitate manual operations, potentially affecting
13
performance. Data redundancy and increased memory usage arise from storing
key names with each value pair, impacting efficiency. A document size limit of 16
MB imposes constraints on handling larger data sets, requiring alternative
approaches. Additionally, MongoDB restricts document nesting to 100 levels,
influencing data organization and structure within documents. (MongoDB
Advantages & Disadvantages, 2023)
Figure 4. How REST API processes between clients and servers (REST API: Key Concepts, Best
Practices, and Benefits, 2022)
14
Figure 4 illustrates the core functionality of the REST API, which mediates
communication between clients and servers while adhering to the principles of
REST. This enables clients to interact with server resources via standard HTTP
methods like GET, POST, PUT, and DELETE, facilitating scalable and stateless
exchange of data and functionality across diverse software systems over the
internet.
GET: The GET method requests data from a specified resource. It retrieves data
without altering the server's state or causing any side effects. It is typically used
for fetching information such as retrieving a resource's details or a collection of
resources.
POST: The POST method is used to send data to a server to process a specified
resource. It can be utilized for various purposes, such as creating a new
resource, updating an existing resource, or triggering server-side processing.
DELETE: The DELETE method is used to remove a specified resource from the
server. It deletes the resource identified by the given URI, effectively removing it
from the server.
3 IMPLEMENTATION
This section is divided into two parts: the website overview provides an overview
of how the website operates, and the back-end implementation demonstrates
how the project was constructed.
The website contains two basic roles, including admin and user. The admin here
is the shelter organization, they can create, update, or delete animals’
information. With the application form, they can check all the forms with users’
information and then do the process for adoption and reply to them through
email. The users can read animals’ information, fill in the form, and donate to the
shelter organization.
The website is called Petner, this name embodies the essence of the platform
dedicated to animal adoption. Inspired by the profound link between humans and
animals, I imagined a space where a "pet" goes beyond companionship to
become a treasured friend and valued "partner" in life's journey. "Petner" hopes
to renew the traditional concept of pet ownership by establishing ties based on
care, compassion, and companionship, as well as recognizing the vital role that
animals play in our lives.
Figure 5 shows the logo for this website, featuring the word "Petner" alongside a
paw icon, which embodies the essence of our platform. Paws represent the feet
of animals, especially dogs and cats, this iconic image will give the website a
recognizable look.
The API planning involves meticulously designing the endpoints, method, and
data input that facilitate communication between the client side and the server.
This process entails defining the functionalities, requests, and responses
expected from the server, laying the groundwork for seamless interaction with the
user interface.
Table 1 offers a diverse range of endpoints and methods crucial for the project's
operations. They feature clear and distinct endpoints, methods, and descriptions,
aimed at facilitating smooth integration into the project. This detailed API plan
serves as the groundwork for effortless interaction between users and the
application, fostering efficient communication and functionality.
To start with the server side, there are some modules and frameworks that need
to be installed: express, nodemon, body-parser, cors, dotenv, jsonwebtoken, and
mongoose. We use the command with the structured npm install and the name of
the modules or frameworks.
storing settings in the environment apart from code. In this project, the .env file
contains sensitive information including database credentials and JWT secret
keys. (Dotenv, 2024)
JSON Web Token (JWT) is a compact and self-contained method for securely
transmitting information between parties as a JSON object. It is commonly used
for authorization purposes, allowing users to access routes and resources based
on the permissions granted by the token. Additionally, JWTs are useful for
securely exchanging information between parties, as they can be signed to verify
the integrity of the claims contained within them. They offer benefits such as
compactness, security, and ease of use across different platforms, making them
a popular choice for information exchange and authentication in web and mobile
applications. (Introduction to JSON Web Tokens, n.d)
Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js.
It is used to manage the relationships between data, provides schema validation,
and is used to translate between objects in code and MongoDB. (Sazib, 2022)
To build the server side, we have to own a database and in this project I use
MongoDB. The database has four collections: animal, user, application, and
category shown in Figure 6:
20
MongoDB Atlas is the cloud server I use to connect with the database MongoDB.
There are two main ways to connect the database to the server, they are “
connect to my application” and “access your data through tools” like MongoDB
compass, MongoDB Shell, MongoDB for VS Code, and Atlas SQL. In this project,
I will connect the database using the “ connect to my application” way which
accesses the Atlas data using MongoDB’s native driver Node.js by connection
string MONGODB_URI with the format:
mongodb+srv://<username>:<password>@[database].cjtuddt.mongodb.net/?retr
yWrites=true&w=majority&appName=[database].
After establishing the database foundation, the schema is a JSON object that
delineates the structure and content of the collection in the project. Many types
will be defined, for example, the type of data, required, enum, etc.
In figure 8, the animal schema is the collection of the types for the data that are
stored for animals such as name, category of this animal, age, gender,
description, and image for each pet. To use the Schema in the collection, we
have to convert it into Model, and figure 9 displays how to convert the
animalSchema to Animal model.
The remaining collections include categories, applications, and users that have a
similar structure to the animal schema and animal model. For more details, table
2 provides a comprehensive overview of the project's data structure and the
relationships that bind them together.
After defining the database collections and the models for each of them, I utilize
Express to define routes for handling various operations related to collection
within the application. I use four basic API methods: POST, GET, PUT, and
DELETE following the table 1.
23
Figure 10 displays how to create the route for the category collection based on
the API planning in table 1. Using the POST method to create the category of
animal following the path /category/create, the GET method to load the category,
the PUT method to update the existing data, and the DELETE method to delete
the existing category. The /:id after the prefixes is the method required input to
work with certain data. In this situation, this /:id becomes the keyword for the
route to edit the information by input the id of specified category. The route
forwards requests to the appropriate controller function for processing.
The same POST method is used to create an animal with a list of requested data
including the name, category, age, gender, description and image of each animal
as shown in figure 12. In case of any errors during the process, such as database
connection issues or validation errors, the error is caught and passed to the error-
handling middleware using the next() function for further handling.
Figure 13 displays code that defines a custom error class named createError,
extending the built-in JavaScript Error class. It accepts two parameters in its
constructor: message and statusCode, which are used to set properties of the
error instance. The statusCode property is used to determine whether the error
status is 'fail' or 'error', based on whether the status code falls within the range of
client errors (4xx). Additionally, it utilizes Error.captureStackTrace() to capture
and store a stack trace for the error instance. The createError class is exported at
the end of the file, so it can be imported and used in other parts of my application
to throw custom errors such as when an animal is not found for showing,
updating, or deleting shown in figure 13 below. These errors are then caught in
the catch block of the try-catch statement and passed to the next middleware
function, which is likely an error-handling middleware that sends an appropriate
response to the client.
message `No animals found` and a status code of 404. Opposite, it sends a
response with a status code of 200 and a JSON body containing a status
property with a value of 'success' and an animal property with the animals array.
In case of any errors occurring during the execution of the function, the catch
block calls the next function with the caught error, passing it to the error-handling
middleware for further processing.
Each category and animal has their unique ID so in case one wants to get data
on one specified category or animal, use the findById method as following figure
15 above. The .findById(req.params.id) is a Mongoose method that finds a single
document in the collection by its ID. The ID is passed as a parameter in the URL
of the HTTP request, and it's accessed through req.params.id. In the code above,
I use this function to get a single animal by ID, to get another document in the
other collections like categories, applications, or users, I also use the same
structure.
During the operation and management of the rescue center, animal information
can be continuously updated and edited. To update new information for animals, I
use the method .findByIdAndUpdate shown in figure 16. This method finds a
27
If organizations have the ability to create, receive, and update data, they also
possess the capability to delete it. Figure 17 demonstrates the method
findByIdAndDelete(req.params.id), which locates a specific document in the
collection by its ID and removes it. This function is typically executed for animals
that have been adopted or are no longer under the care of the organization.
The home page serves as the gateway to a website, offering users a welcoming
interface and intuitive navigation options. It provides quick access to essential
features like account registration, login, and the latest updates. With a clean
design and user-friendly layout, the home page ensures visitors can easily find
28
the information they need. Engaging visuals and clear call-to-action buttons guide
users through their journey, enhancing their overall experience on the site.
The register page is designed for users to initiate the creation of a new account.
To proceed with the registration process, users are required to input their full
name, email, and password. Once all the necessary information is provided,
users can click on the "Register" button to submit their data to the backend
endpoint "/register" for validation. Users need to adhere to the specified criteria
for email formatting and password complexity to successfully create their
29
accounts. In case of any incorrect inputs, users will receive immediate error
messages displayed above the register button, prompting them to correct their
entries. Figure 19 illustrates the register page.
On the server side, using the POST method to request the /register the controller
first checks if a user with the provided email already exists in the database. The
.findOne method will check the existing email in the users collection, if a user with
the same email is found, it creates a new error with the message “User already
exists”. Otherwise, the User.create function will create a new user with the data in
req.body including name, email, and password.
30
Figure 21 displays the code for the register function, which handles user
registration. After successfully creating the user, a JSON Web Token (JWT) is
crafted using the user's ID and a secret token. This token, coupled with user
details, is then provided in the response. Utilizing the jwt.sign method, the code
incorporates the user's ID (newUser._id) into the token payload, signs it with a
designated secret key loaded from the .env file, and establishes a 30-day
expiration period (expiresIn: '30d'). Subsequently, the generated token is stored
in the token variable for authentication purposes.
After registering for an account, users can enter their email and password to
authenticate their identity on subsequent visits. Figure 22 illustrates the log in
page.
Upon submitting the login credentials, the data is sent to the backend endpoint
"/login" for validation using the POST method. Similar to the registration process,
the controller first queries the database to find a user with the provided email
using the .findOne method. If no user is found, an error message "User not
found" is generated and returned to the user interface. If a user is found, the
controller proceeds to verify the entered password against the hashed password
stored in the database using the userSchema.methods.matchPassword function,
which meticulously compares the provided password with its hashed equivalent.
If the passwords match, a JSON Web Token (JWT) is generated using the user's
ID and a secret token, and this token, along with the user details, is returned in
the response. Conversely, if the passwords do not match, an error message “
Invalid email or password” is returned, signaling an unsuccessful login attempt.
Upon successful login, the user's name will automatically be displayed. Figure 24
shows a user menu with several functions, including managing applications,
donation history, settings, and logout. In the current version of this project, only
the logout function is operational, with plans to enhance the other features in
future updates.
The main function of this website is to facilitate animal adoption, allowing users to
access and find a companion that matches their preferences. Through an intuitive
interface, users can browse available pets, filter by categories such as All, Cat, or
Dog, and view detailed information about each animal. This streamlined process
ensures that finding a new pet is both efficient and enjoyable.
Figure 25 illustrates the Adopt page, which provides a user-friendly interface for
potential pet adopters to browse a list of pets available at the shelter. This React
component utilizes state management to store pet data fetched from an API
endpoint. Upon loading, it retrieves the pet data using Axios and updates both the
complete and filtered lists of pets. The page includes a dynamic filtering function
34
that enhances the browsing experience by allowing users to refine their search by
category—All, Cat, or Dog—through clearly labeled buttons. When a filter button
is clicked, the list of pets updates to show only those matching the selected
category. Figure 26 shows all dogs in the Dog category, demonstrating how the
filter function personalizes the user experience.
Users can flip between pages using the radio buttons below the item display. The
buttons are designed to identify the current page and are deactivated when
already chosen, providing clear visual feedback and improving the user
experience. The combination of dynamic filtering and effective pagination allows
35
visitors to traverse the available pets, locate important information, and have a
smooth browsing experience.
Figure 27 shows the animal details page. The website has an easy-to-navigate
style with a "Her Detail" or "His Detail" headline dependent on the pet's gender
and a button to start the adoption process. When users click the "Adopt This Little
Friend!" button, a dialog box displays, describing crucial adoption considerations
and actions. This dialog emphasizes key points such as age requirements, the
36
The main function of this website is to adopt animals by filling out an adoption
application. Continue using the create() function to create a new application using
the POST method, which creates a new adoption application asynchronously
using the data provided in the request body as shown in figure 28.
Figure 29 shows the application form where the applicant must be over 20 years
old and must complete all required information. Once the application is
successfully created and stored in the database, the application responds with a
JSON object containing a success status and a congratulatory message
confirming delivery to the screen.
Once completed, applications will be sent directly to the organization's email. The
organization then proceeds with the adoption process by thoroughly examining
each application and evaluating the applicant's details to determine if they are a
match for the desired animal. Following this assessment, the organization will
notify the results to the applicant via email and conduct a phone interview. In this
communication, additional questions may be included to determine the
candidate's compatibility with the responsibilities associated with pet care,
thereby facilitating the process. comprehensive review.
38
The website facilitates both pet adoption and donations to support the
organization's mission. Users have the option to contribute financially through
PayPal, selecting between one-time or monthly donations. This functionality not
only fosters community engagement but also provides vital resources for
maintaining the shelter's operations. By leveraging PayPal's secure payment
platform, users can conveniently support the organization's cause, ensuring the
well-being of sheltered animals and enabling continued outreach efforts. In Figure
30, the donation interface is depicted, showing the user a structured layout of
suggested donation amounts between 5 and 200 euros. Additionally, users have
the flexibility to manually enter a custom donation amount.
The project uses the PayPal REST SDK in combination with the PayPal sandbox
environment to provide secure and frictionless contribution transactions. By
interacting with the PayPal API, the server-side code orchestrates payment
generation and execution, assuring reliable payment processing. On the client
39
Figure 31 shows the PayPal payment interface, users can log in to their PayPal
account and initiate payment.
Both components offer a button that redirects users back to the homepage,
ensuring a seamless user experience regardless of the donation outcome. This
implementation ensures that users receive clear feedback on their donation
attempts and have an easy way to return to the main page.
being accessible and responsive, ultimately helping to build trust and strengthen
relationships with potential adopters, donors, and volunteers.
Figure 34 shows the contact form. When a user fills out the form and hits send,
the fetch API sends the form data to the Web3Forms endpoint via a POST
request. This data includes user input such as name, phone number, email, and
message. The Web3Forms service then processes this data and sends it directly
to the organization's email, ensuring that all communications are received
promptly. This setup not only simplifies the submission process but also
enhances reliability and security, ensuring that user messages are efficiently
conveyed to the shelter's team.
4 FUTURE DEVELOPMENT
In addition to the existing functionalities, the project has significant potential for
future development. One key aspect of this is the implementation of an admin
dashboard, empowering managers to perform operations with animal and user
data more intuitively. This dashboard will streamline tasks such as managing
animal profiles, updating pet statuses, and evaluating adoption applications.
Moreover, integrating an online adoption application processing feature will
42
5 CONCLUSION
The goal of this project was to build an animal adoption website for animal rescue
organizations, thereby finding more connections between pets and people, to
spread kindness and love for animals.
43
Looking ahead, the future of the project holds immense promise and potential for
growth. By continuing to innovate and expand upon its existing functionalities, the
project aims to further solidify its position as a valuable resource for animal
rescue organizations and prospective adopters alike. Through the implementation
of advanced features such as the admin dashboard, online adoption application
processing, and enhanced user profiles, the project will continue to evolve to
meet the changing needs of its users and stakeholders. Additionally, by fostering
community engagement through social sharing capabilities and virtual adoption
events, the project will continue to raise awareness about animal welfare and
facilitate meaningful connections between pets and people. With a steadfast
commitment to excellence and ongoing development, the project is poised to
make a lasting impact in the realm of animal adoption and welfare for years to
come.
44
REFERENCES
CHAUHAN, P. 2023. How does Virtual DOM actually work in Reactjs?. Web
page. Available at: https://copperchips.com/how-does-virtual-dom-actually-work-
in-reactjs/ [Accessed 9 March 2024].
Daigle, K. 2023. Octoverse: The state of open source and rise of AI in 2023. Web
page. Available at: https://github.blog/2023-11-08-the-state-of-open-source-and-
ai/ [Accessed 5 March 2024].
Grigutytė, M. 2023. What is bcrypt and how does it work?. Web page. Available
at: https://nordvpn.com/fr/blog/what-is-
bcrypt/#:~:text=Bcrypt%20is%20a%20valuable%20tool,to%20break%20the%20b
crypt%20hash. [Accessed 1 April 2024].
Introduction to JSON Web Tokens. n.d. JWT.io. Web page. Available at:
https://jwt.io/introduction [Accessed 1 April 2024].
Kouchi, B. 2024. How to restart your node.js apps automatically with nodemon.
Web page. Available at:
https://www.digitalocean.com/community/tutorials/workflow-nodemon [Accessed
1 April 2024].
REST API: Key Concepts, Best Practices, and Benefits. 2022. AltexSoft:
46
Sazib, M. 2022. Mongoose Discusses Schema and Model Work. Web page.
Available at: https://medium.com/@musasazib/mongoose-discusses-schema-
and-model-work-81c5b4b73975 [Accessed 24 March 2024].
Top Features of MongoDB. n.d. Board Infinity. Web page. Available at:
https://www.boardinfinity.com/blog/top-features-of-mongodb/
[Accessed 23 March 2024].
47
LIST OF FIGURES