Scotch Io Tutorials Creating A Single Page Todo App With Node and Angular Fbclid IwAR1UyBth4V9M1N61nmNiX2LNv7aQb6SvdYGy5fGuJydW4l sSS9iX8ZrSo
Scotch Io Tutorials Creating A Single Page Todo App With Node and Angular Fbclid IwAR1UyBth4V9M1N61nmNiX2LNv7aQb6SvdYGy5fGuJydW4l sSS9iX8ZrSo
CODE DEMO
Today we will be creating a very simple Todo application using the MEAN (Mongo, Express,
Angular, Node) stack. We will be creating:
While the application is simple and beginner to intermediate level in its own right, the
concepts here can apply to much more advanced apps. The biggest things we should focus
on is using Node as an API and Angular as the frontend. Making them work together can be
a bit confusing so this tutorial should help alleviate some confusion. Buckle those seatbelts;
this could be a long one.
todoaholic
Base Setup
File Structure
We are going to keep the le structure very simple and put most of the code for our Node
application into the server.js le. In larger applications, this should be broken down
further to separate duties. Mean.io is a good boilerplate to see best practices and how to
separate le structure. Let's go ahead and create our simpler le structure and edit the les
as we go along.
- public <!-- holds all our files for our frontend angu
----- core.js <!-- all angular code for our app -->
Installing Modules
In Node, the package.json le holds the con guration for our app. Node's package
manager ( npm) will use this to install any dependencies or modules that we are going to use.
In our case, we will be using Express ( popular Node framework) and Mongoose (object
modeling for MongoDB).
"name" : "node-todo",
"version" : "0.0.0",
"main" : "server.js",
"author" : "Scotch",
"dependencies" : {
"express" : "~4.7.2",
"mongoose" : "~3.6.2",
"morgan" : "~1.2.2",
"body-parser": "~1.5.2",
"method-override": "~2.1.2"
Now if we run npm install , npm will look at this le and install Express and Mongoose.
npm-install
In our package.json le, we told it that our main le would be server.js . This is the
main le for our Node app and where we will con gure the entire application.
For now, we will just con gure the app for Express, our MongoDB database, and listening on
a port.
// server.js
// set up ========================
// configuration =================
mongoose.connect('mongodb://node:[email protected]:2701
app.use(express.static(__dirname + '/public')); //
app.use(morgan('dev')); //
app.use(bodyParser.urlencoded({'extended':'true'})); //
app.use(bodyParser.json()); //
app.use(methodOverride());
Just with that bit of code, we now have an HTTP server courtesy of Node. We have also
created an app with Express and now have access to many bene ts of it. In our
app.configure section, we are using express modules to add more functionality to our
application.
Database Setup
We will be using a remote database hosted on Modulus.io. They provide a great service and
give you $15 upfront to use as you see t. This is great for doing testing and creating
databases on the y.
Modulus will provide the database URL you need and you can use mongoose.connect to
connect to it. That's it.
Now that we have our package.json and server.js started up, we can start up our
server and see what's going on. Just go into your console and use the following command:
node server.js Now you have a server listening on port 8080. You can't see anything in
your browser at http://localhost:8080 yet since we didn't con gure our application to output
anything. But it's a start!
Automatically restart server when les change: By default, node will not monitor for le
changes after your server has been started. This means you'd have to shut down and start
the server every time you made a le change. This can be xed with nodemon. To use:
install nodemon globally npm install -g nodemon . Start your server with nodemon
server.js now. Smooth sailing from there.
Application Flow
Now a brief overview of how all our moving parts will work together. There are a lot of
different ideas and technologies involved in this application that it is easy to get mixed up
with them all. In our diagram below, we explain a bit of the separation of tasks and how the
parts tie in together.
mean
Angular is on its own in the frontend. It accesses all the data it needs through the Node API.
Node hits the database and returns JSON information to Angular based on the RESTful
routing.
This way, you can separate the frontend application from the actual API. If you want to
extend the API, you can always build more routes and functions into it without affecting the
frontend Angular application. This way you can eventually build different apps on different
platforms since you just have to hit the API.
Todo Model
We must de ne our model for our Todos. We'll keep this simple. After the con guration
section and before the listen section, we'll add our model.
text : String
});
That is all we want. Just the text for the todo. MongoDB will automatically generate an _id
for each todo that we create also.
...
// routes ============================================================
// api -----------------------------------------------------------
Todo.find(function(err, todos) {
if (err)
res.send(err)
});
});
Todo.create({
text : req.body.text,
done : false
}, function(err, todo) {
if (err)
res.send(err);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
});
// delete a todo
Todo.remove({
_id : req.params.todo_id
}, function(err, todo) {
if (err)
res.send(err);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
});
...
Based on these routes, we've built a table to explain how a frontend application should
request data from the API.
HTTP Verb URL Description
Inside of each of our API routes, we use the Mongoose actions to help us interact with our
database. We created our Model earlier with var Todo = mongoose.model and now we
can use that to nd, create, and remove. There are many more things you can do and I would
suggest looking at the of cial docs to learn more.
Our API is done! Rejoice! If you start up your application, you can interact with it at
localhost:8080/api/todos to get all the todos. There won't be anything currently since
you haven't added any.
We have created a Node application, con gured our database, generated our API routes,
and started a server. So much already done and still a little bit longer to go!
The work that we've done so far can stand on its own as an application. It can be an API we
use let applications and users connect with our content.
We want to be the rst to use our brand new API that we've just created. This is one of my
favorite terms that I learned about last month: We will be dogfooding. We could treat this as
we are our very rst client to use our new API. We are going to keep this simple so we'll have
just our index.html and core.js to de ne our frontend.
We have already de ned our API routes. Our application's API is accessible from
/api/todos , but what about our frontend? How do we display the index.html le at our
home page?
We will add one route to our server.js le for the frontend application. This is all we need
to do since Angular will be making a single page application and handle the routing.
After our API routes, and before the app.listen , add this route:
// server.js
...
// application --------------------------------------------------
});
...
Let's go through our Angular setup rst. We have to create a module, create a controller,
and de ne functions to handle todos. Then we can apply to view.
// public/core.js
$scope.formData = {};
// when landing on the page, get all todos and show them
$http.get('/api/todos')
.success(function(data) {
$scope.todos = data;
console.log(data);
})
.error(function(data) {
});
// when submitting the add form, send the text to the node API
$scope.createTodo = function() {
$http.post('/api/todos', $scope.formData)
.success(function(data) {
$scope.todos = data;
console.log(data);
})
.error(function(data) {
});
};
$scope.deleteTodo = function(id) {
$http.delete('/api/todos/' + id)
.success(function(data) {
$scope.todos = data;
console.log(data);
})
.error(function(data) {
});
};
We also create our functions to get all todos, create a todo, and delete a todo. All these will
be hitting the API we just created. On page load, we will GET /api/todos and bind the
JSON we receive from the API to $scope.todos . We will then loop over these in our view to
make our todos.
We'll follow a similar pattern for creating and deleting. Run our action, remake our todos list.
Here we will keep it simple. This is the HTML needed to interact with Angular. We will:
<!doctype html>
<html ng-app="scotchTodo">
<head>
<meta charset="utf-8">
<style>
html { overflow-y:scroll; }
body { padding-top:50px; }
#todo-list { margin-bottom:30px; }
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.m
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angul
<script src="core.js"></script>
</head>
<body ng-controller="mainController">
<div class="container">
<!-- HEADER AND TODO COUNT -->
</div>
<label>
</label>
</div>
</div>
</div>
<form>
<div class="form-group">
</div>
</form>
</div>
</div>
</div>
</body>
</html>
todoaholic
Conclusion
Now we have a fully working application that will show, create, and delete todos all via API
(that we built!). That was quite a day. We've done so much. Just an overview of what we've
accomplished:
Go ahead and download the code on Github and tweak it or test it. To get it all up and
running:
I hope this was insightful on how to have lots of moving parts work together. In the future,
we will look at separating our server.js le since that got a little crazy.
This article is part of our Node and Angular To-Do App series.
1. Creating a Single Page To-do App with Node and Angular
2. Node Application Organization and Structure
3. Angular Modules: Controllers and Services
Read next...
Chris on Code
Chris on Code
F O L LO W @ C H R I S O N C O D E
Founder of Scotch.io. Google Developer Expert in Web Technologies. Slapping the keyboard until something
good happens.