Solution in the solution branch.
Check Install
-
You should have Node.js and NPM installed from installfest. Run the Terminal commands
which nodeandwhich npmto check that they are installed. If they are installed, you will see a file path after each command, like/usr/local/bin/node. -
Only if you do not have node and npm installed: Install Node & NPM
- To install Homebrew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"- To install Node.js:
brew install node - If you encounter issues, ask for help!
Initialize a Node.js Project with Express
-
Go to your
~/wdidirectory and clone this repo. (You don't need to fork.) From inside yourexpress-introdirectory, enter the Terminal commandnpm init. It asks a series of questions about your project and uses the information to create apackage.jsonfile for you. For now, we'll use all of the defaults except "entry point". Type inserver.jsfor your entry point, and then you can just hit enter untilnpm initis done. Take a look atpackage.jsonto see the initial informationnpm inithelps you set up. -
Add express to the local project using
npm. Use thesaveoption so that NPM automatically adds express to your dependencies inpackage.json.
npm install express --saveNotice that a new folder called node_modules was created. Open it up and you'll see that there is an express folder. node_modules is where the dependencies in package.json are downloaded to. If you look at package.json again, you'll see express has been added as a dependency for this project.
Express Hello World!
- Create a
server.jsfile and add this basic hello world code:
// server.js
// SERVER-SIDE JAVASCRIPT
var express = require('express');
var app = express();
// Allow CORS: we'll use this today to reduce security so we can more easily test our code in the browser.
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(process.env.PORT || 3000, function () {
console.log('Example app listening at http://localhost:3000/');
});- Add a comment above each line of code saying what each line does.
Hint: Reference the express documentation. Hint:
process.env.PORT || 3000means "in production use the production port, otherwise use 3000 (for development)".
-
Run
node server.jsin the Terminal. You should see 'Example app listening at http://localhost:3000/' in the Terminal. When we're using express, this is where our server-side console logs show up! Also, visithttp://localhost:3000/in your browser. You should see "Hello World!" The browser console only shows client-side console outputs. Every time you make a change in your server code and want it to run, you need to end the previous server and runnode server.js. -
Console log the
req(request) and theres(response) objects inside your server code'sapp.getmethod for the/path. (The/path is often called the "root" path.) Restart the server and briefly check out what thereqandresare.
Add Some Data on the Server
- In server.js, add some starter data (often called "seed data") to serve when the users visit '/api/albums'.
// server.js
var albums = [
{
title: 'Cupid Deluxe',
artist: 'Blood Orange'
},
{
title: 'M3LL155X - EP',
artist: 'FKA twigs'
},
{
title: 'Fake History',
artist: 'letlive.'
}
];- To have this data be accessible, we'll need to set up a route to serve it. Add an
app.getmethod for the path/api/albums. Inside the new route, useres.json(albums)to respond with some JSON containing all the albums from our albums variable.
Restart your server, and you should see our albums when you use postman to request the
http://localhost:3000/api/albumsURL. You could also try using curl:curl -X GET http://localhost:3000/api/albumsor just your browser.
Request Data From the Server
- Let's get this working with our index page now. In your browser, open
index.htmland then open the javascript console. You should see 'Sanity Check: JS is working!' Try running the following AJAX request in the JavaScript console:
$.ajax({
method: 'GET',
url: 'http://localhost:3000/api/albums',
success: handleSuccess,
error: handleError
});
function handleSuccess(json) {
console.log(json);
}
function handleError(xhr, status, errorThrown) {
console.log('uh oh');
}Note: you must be on a page with jQuery in order to use .ajax in the browser console! Fortunately, the included index.js does have jQuery.
You should get something back like:
[Object, Object, Object]
Dig into those and see what they look like.
-
Next edit
app.jsto run the same ajax call as above and console log the data. Remember to put your ajax call inside the handler for the document ready event:$(document).ready(function() {}). Consider moving the success handling function definition outside the ajax call, since it's about to get more complicated! -
Once you have that, edit
app.jsto display this data on yourindex.htmlpage using jQuery. Decide how you want it to look. Hint: You might also find it useful to editindex.html! -
Restart your server and refresh the page. You should see a list of album titles on the page.
Serve our index page
At this point, server.js and our client-side files (index.html, app.js, and styles.css) are only connected by the ajax request made in app.js. Let's make a route to serve our index.html. We're just going to serve the index on the route GET / for now.
- First let's be sure we follow a good convention for file location and directory structure. This will help a lot when organizing larger projects. Move
index.htmlinto a newviewsdirectory. (Create the directory first.)
A good express file tree structure:
├── server.js // your server code
├── package.json // project info and dependencies; changed by npm init or npm install --save somePackage
├── public // i.e. client-side
│ ├── images // images to serve to client
│ ├── scripts // or js
│ └── app.js // client-side javascript file
│ └── styles // or css
│ └── styles.css
├── vendor // an optional 2nd public directory that includes jQuery & bootstrap if we choose not to use a CDN
└── views // html files that we'll serve
│ ├── index.html
- We're just going to serve our index on the root route,
/, so change the current GET/route from serving the string'hello world'to instead sending theindex.htmlfile, withres.sendFile('views/index.html' , { root : __dirname});. Curious about what this does? Try logging__dirnameto your console.
If you restart your server now and visit 'localhost:3000' in the browser, you'll notice the site now shows the contents of the html file instead of just the hello world message! Congratulations; you now have a server serving a page!
But the page looks a little different than when we just opened it as a file, and you'll see some errors in the console. That's because we're not yet serving the js and css files the page needs. Let's fix that next.
Add Static Files (CSS, JS, Images)
-
Make a directory in your project called
public; then createpublic/scripts,public/stylesandpublic/imagessubdirectories. Movestyles.css, andapp.js, into their public subdirectories. These files are called static files. (You can delete the old directories they were in.) -
Set up the express app to serve the static files (actually, the whole public directory.)
// server.js
app.use(express.static('public'));-
Get a
console.log("Sanity Check: JS is working!")from yourapp.jsto appear in your browser dev tools console. -
Get the css styles in
styles.cssworking again on the index page. -
Everything should be working again now, and you should see your albums when you visit
localhost:3000. If not, fix it!
Challenge
We're making a weird app. Albums and taquerias. Treat your senses.
- Add some taqueria seed data to your server file.
// server.js
var taquerias = [
{ name: "La Taqueria" },
{ name: "El Farolito" },
{ name: "Taqueria Cancun" }
];- Add a route to your server side javascript that clients can use to get taqueria data. The route's path should be
/api/taquerias. Instead ofres.send(for simple strings) orres.sendFile, this route will useres.json.
app.get('/api/taquerias', function (req, res) {
res.json(taquerias);
});-
Navigate to http://localhost:3000/api/taquerias (remember to restart your server first!) and check that the data is showing up.
-
In your
app.jsfile, write a jQuery AJAX request to get the taqueria data. When the response comes back, display all the taqueria names above the albums on your site's root page (localhost:3000/).
Want a reminder of the ajax call structure? Click here!
$.ajax({
method: 'GET',
url: '/api/taquerias',
success: handleResponse
});
function handleResponse(json) {
// your code here
}- Add a
vendorfolder to your project. Thevendorfolder is traditionally used for third-party (external) library code. Download Bootstrap's CSS and JavaScript files and add them to thevendorfolder. Can you include Bootstrap in your project from this location instead of the CDN? What is the benefit of having a separatevendorfolder for external front-end libraries?
Hint: Remember to serve the static vendor files to make them available to your front end.
// server.js
app.use(express.static('vendor'));- Add an image to your
public/imagesfolder and display it inindex.html.
