Preface |
|
xv | |
Acknowledgments |
|
xvii | |
About this book |
|
xix | |
About the authors |
|
xxii | |
About the cover illustration |
|
xxiii | |
|
Part 1 Setting the baseline |
|
|
1 | (50) |
|
1 Introducing full-stack development |
|
|
3 | (48) |
|
1.1 Why learn the full stack? |
|
|
4 | (1) |
|
A brief history of web development |
|
|
5 | (2) |
|
The trend toward full-stack developing |
|
|
7 | (1) |
|
Benefits of full-stack development |
|
|
7 | (1) |
|
Why the MEAN stack specifically ? |
|
|
8 | (1) |
|
1.2 Introducing Node.js: The web server/platform |
|
|
8 | (1) |
|
JavaScript: The single language through the slack |
|
|
9 | (4) |
|
Fast, efficient, and scalable 9m Using prebuilt packages via npm |
|
|
13 | (1) |
|
1.3 Introducing Express: The framework |
|
|
13 | (1) |
|
|
14 | (1) |
|
Routing URLs to responses |
|
|
14 | (1) |
|
|
14 | (1) |
|
Remembering visitors with session support |
|
|
14 | (1) |
|
1.4 Introducing MongoDB: The database |
|
|
15 | (1) |
|
Relational databases vs. document stores |
|
|
15 | (1) |
|
MongoDB documents: JavaScript data store |
|
|
15 | (1) |
|
More than just a document database |
|
|
16 | (1) |
|
What is MongoDB not good for? |
|
|
16 | (1) |
|
Mongoose for data modeling and more |
|
|
16 | (2) |
|
1.5 Introducing Angular: The front-end framework |
|
|
18 | (1) |
|
|
18 | (1) |
|
Two-way data binding: Working with datainapage |
|
|
18 | (1) |
|
Using Angular to load new pages |
|
|
19 | (1) |
|
|
19 | (1) |
|
|
20 | (1) |
|
|
20 | (1) |
|
Twitter Bootstrap for user interface |
|
|
20 | (1) |
|
|
21 | (1) |
|
|
22 | (1) |
|
1.7 Putting it together with a practical example |
|
|
22 | (1) |
|
Introducing the example application |
|
|
22 | (2) |
|
How the MEAN stack components work together |
|
|
24 | (1) |
|
2 Designing a MEAN stack architecture |
|
|
25 | (1) |
|
2.1 A common MEAN stack architecture |
|
|
26 | (1) |
|
|
27 | (1) |
|
|
27 | (1) |
|
Analytics and browser history |
|
|
28 | (1) |
|
|
28 | (1) |
|
|
29 | (1) |
|
2.3 Designing a flexible MEAN architecture |
|
|
29 | (1) |
|
Requirements for a blog engine |
|
|
30 | (1) |
|
A blog engine architecture |
|
|
31 | (3) |
|
Best practice: Building an internal API for a data layer |
|
|
34 | (1) |
|
2.4 Planning a real application |
|
|
35 | (1) |
|
Planning the application at a high level |
|
|
36 | (1) |
|
Architecting the application |
|
|
37 | (1) |
|
Wrapping everything in an Express project |
|
|
38 | (1) |
|
|
39 | (1) |
|
2.5 Breaking the development into stages |
|
|
40 | (1) |
|
Rapid prototype development stages |
|
|
41 | (1) |
|
|
42 | (6) |
|
2.6 Hardware architecture |
|
|
48 | (1) |
|
|
48 | (1) |
|
|
48 | (3) |
|
Part 2 Building a Node web application |
|
|
51 | (188) |
|
3 Creating and setting up a MEAN project |
|
|
53 | (28) |
|
3.1 A brief look at Express, Node, and npm |
|
|
55 | (1) |
|
Defining packages with package.json |
|
|
55 | (1) |
|
Working with dependency versions in package.json |
|
|
56 | (1) |
|
Installing Node dependencies with npm |
|
|
56 | (2) |
|
3.2 Creating an Express project |
|
|
58 | (1) |
|
|
58 | (1) |
|
Verifying the installations |
|
|
59 | (1) |
|
Creating a project folder |
|
|
59 | (1) |
|
Configuring an Express installation |
|
|
59 | (2) |
|
Creating an Express project and trying it out |
|
|
61 | (2) |
|
Restarting the application |
|
|
63 | (2) |
|
3.3 Modifying Express for MVC |
|
|
65 | (1) |
|
|
65 | (1) |
|
Changing the folder structure |
|
|
66 | (1) |
|
Using the views and routes relocated folders |
|
|
67 | (1) |
|
Splitting controllers from routes |
|
|
68 | (3) |
|
3.4 Importing Bootstrap for quick, responsive layouts |
|
|
71 | (1) |
|
Downloading Bootstrap and adding it to the application |
|
|
72 | (1) |
|
Using Bootstrap in the application |
|
|
72 | (3) |
|
3.5 Making it live on Heroku |
|
|
75 | (1) |
|
|
75 | (2) |
|
Pushing the site live using Git |
|
|
77 | (4) |
|
4 Building a static site with Node and Express |
|
|
81 | (38) |
|
4.1 Defining the routes in Express |
|
|
83 | (1) |
|
Different controller files for different collections |
|
|
84 | (1) |
|
4.2 Building basic controllers |
|
|
85 | (1) |
|
|
85 | (2) |
|
Testing the controllers and routes |
|
|
87 | (1) |
|
|
88 | (1) |
|
|
88 | (2) |
|
Setting up the HTML framework with Pug templates and Bootstrap |
|
|
90 | (4) |
|
|
94 | (5) |
|
4.4 Adding the rest of the views |
|
|
99 | (1) |
|
|
99 | (3) |
|
|
102 | (2) |
|
|
104 | (2) |
|
4.5 Taking the data out of the views and making them smarter |
|
|
106 | (1) |
|
Moving data from the view to the controller |
|
|
107 | (2) |
|
Dealing with complex, repeating data patterns |
|
|
109 | (4) |
|
Manipulating the data and view with code |
|
|
113 | (1) |
|
Using includes and mixins to create reusable layout components |
|
|
113 | (2) |
|
Viewing the finished homepage |
|
|
115 | (2) |
|
Updating the rest of the views and controllers |
|
|
117 | (2) |
|
5 Building a data model with MongoDB and Mongoose |
|
|
119 | (41) |
|
5.1 Connecting the Express application to MongoDB by using Mongoose |
|
|
121 | (1) |
|
Adding Mongoose to your application |
|
|
122 | (1) |
|
Adding a Mongoose connection to your application |
|
|
123 | (5) |
|
|
128 | (2) |
|
What is Mongoose and how does it work ? |
|
|
130 | (1) |
|
How does Mongoose model data? |
|
|
131 | (1) |
|
Breaking down a schema path |
|
|
131 | (1) |
|
5.3 Defining simple Mongoose schemas |
|
|
132 | (1) |
|
The basics of setting up a schema |
|
|
133 | (2) |
|
Using geographic data in MongoDB and Mongoose |
|
|
135 | (2) |
|
Creating more complex schemas with subdocuments |
|
|
137 | (5) |
|
|
142 | (2) |
|
Compiling Mongoose schemas into models |
|
|
144 | (2) |
|
5.4 Using the MongoDB shell to create a MongoDB database and add data |
|
|
146 | (1) |
|
|
146 | (2) |
|
Creating a MongoDB database |
|
|
148 | (3) |
|
5.5 Getting your database live |
|
|
151 | (1) |
|
Setting up mLab and getting the database URI |
|
|
151 | (2) |
|
|
153 | (2) |
|
Making the application use the right database |
|
|
155 | (5) |
|
6 Writing a REST API: Exposing the MongoDB database to the application |
|
|
160 | (41) |
|
6.1 The rules of a REST API |
|
|
161 | (1) |
|
|
162 | (1) |
|
|
163 | (2) |
|
Responses and status codes |
|
|
165 | (2) |
|
6.2 Setting up the API in Express |
|
|
167 | (1) |
|
|
167 | (3) |
|
Creating the controller placeholders |
|
|
170 | (1) |
|
Returning JSON from an Express request |
|
|
170 | (1) |
|
|
171 | (1) |
|
|
171 | (2) |
|
6.3 GET methods: Reading data from MongoDB |
|
|
173 | (1) |
|
Finding a single document in MongoDB using Mongoose |
|
|
173 | (4) |
|
Finding a single subdocument based on IDs |
|
|
177 | (2) |
|
Finding multiple documents with geospatial queries |
|
|
179 | (7) |
|
6.4 POST methods: Adding data to MongoDB |
|
|
186 | (1) |
|
Creating new documents in MongoDB |
|
|
186 | (2) |
|
Validating the data using Mongoose |
|
|
188 | (1) |
|
Creating new subdocuments in MongoDB |
|
|
188 | (4) |
|
6.5 PUT methods: Updating data in MongoDB |
|
|
192 | (1) |
|
Using Mongoose, to update a document in MongoDB |
|
|
193 | (1) |
|
Using the Mongoose save method |
|
|
193 | (2) |
|
Updating an existing subdocument in MongoDB |
|
|
195 | (2) |
|
6.6 DELETE method: Deleting data from MongoDB |
|
|
197 | (1) |
|
Deleting documents in MongoDB |
|
|
197 | (1) |
|
Deleting a subdocument from MongoDB |
|
|
198 | (3) |
|
7 Consuming a REST API: Using an API from inside Express |
|
|
201 | (38) |
|
7.1 How to call an API from Express |
|
|
202 | (3) |
|
Adding the request module to your project |
|
|
202 | (1) |
|
Setting up default options |
|
|
203 | (1) |
|
|
203 | (2) |
|
7.2 Using lists of data from an API: The Loc8r homepage |
|
|
205 | (10) |
|
Separating concerns: Moving the rendering into a named function |
|
|
205 | (1) |
|
|
206 | (1) |
|
Using the API response data |
|
|
207 | (2) |
|
Modifying data before displaying it: fixing the distances |
|
|
209 | (2) |
|
Catching errors returned by the API |
|
|
211 | (4) |
|
7.3 Getting single documents from an API: The Loc8r Details page |
|
|
215 | (9) |
|
Setting URLs and routes to access specific MongoDB documents |
|
|
215 | (2) |
|
Separating concerns: Moving the rendering into a named function |
|
|
217 | (1) |
|
Querying the API using a unique ID from a URL parameter |
|
|
217 | (1) |
|
Passing the data from the API to the view |
|
|
218 | (2) |
|
Debugging and fixing the view errors |
|
|
220 | (1) |
|
Formatting dates using a Pug mixin |
|
|
221 | (1) |
|
Creating status-specific error pages |
|
|
222 | (2) |
|
7.4 Adding data to the database via the API: add Loc8r reviews |
|
|
224 | (7) |
|
Setting up the routing and views |
|
|
225 | (4) |
|
POSTing the review data to the API |
|
|
229 | (2) |
|
7.5 Protecting data integrity with data validation |
|
|
231 | (8) |
|
Validating at the schema level with Mongoose |
|
|
231 | (4) |
|
Validating at the application level with Node and Express |
|
|
235 | (1) |
|
Validating in the browser withjQuery |
|
|
236 | (3) |
|
Part 3 Adding a dynamic front end with Angular |
|
|
239 | (104) |
|
8 Creating an Angular application with TypeScript |
|
|
241 | (33) |
|
8.1 Getting up and running with Angular |
|
|
242 | (8) |
|
Using the command line to create a boilerplate Angular app |
|
|
242 | (2) |
|
|
244 | (1) |
|
The source code behind the application |
|
|
245 | (5) |
|
8.2 Working with Angular components |
|
|
250 | (14) |
|
Creating a new home-list component |
|
|
250 | (2) |
|
Creating the HTML template |
|
|
252 | (2) |
|
Moving data out of the template into the code |
|
|
254 | (3) |
|
Using class member data in the HTML template |
|
|
257 | (7) |
|
8.3 Getting data from an API |
|
|
264 | (6) |
|
|
264 | (3) |
|
|
267 | (3) |
|
8.4 Putting an Angular application into production |
|
|
270 | (4) |
|
Building an Angular application for production |
|
|
270 | (1) |
|
Using the Angular application from the Express site |
|
|
271 | (3) |
|
9 Building a single-page application with Angular: Foundations |
|
|
274 | (30) |
|
9.1 Adding navigation in an Angular SPA |
|
|
275 | (8) |
|
Importing the Angular router and defining the first route |
|
|
276 | (1) |
|
|
276 | (1) |
|
Creating a component for the framework and navigation |
|
|
277 | (2) |
|
Defining where to display the content using router-outlet |
|
|
279 | (3) |
|
Navigating between pages 279* Adding active navigation styles |
|
|
282 | (1) |
|
9.2 Building a modular app using multiple nested components |
|
|
283 | (8) |
|
Creating the main homepage component |
|
|
284 | (1) |
|
Creating and using reusable subcomponents |
|
|
285 | (6) |
|
9.3 Adding geolocation to find places near you |
|
|
291 | (7) |
|
Creating an Angular geolocation service |
|
|
292 | (1) |
|
Adding the geolocation service to the application |
|
|
293 | (1) |
|
Using the geolocation service from the home-list component |
|
|
293 | (5) |
|
9.4 Safely binding HTML content |
|
|
298 | (4) |
|
Adding the About page content to the app |
|
|
298 | (1) |
|
Creating a pipe to transform the line breaks |
|
|
299 | (2) |
|
Safely binding HTML by using a property binding |
|
|
301 | (1) |
|
|
302 | (2) |
|
10 Building a single-page application with Angular: The next level |
|
|
304 | (39) |
|
10.1 Working with more-complex views and routing parameters |
|
|
305 | (16) |
|
|
305 | (1) |
|
Creating the required components |
|
|
306 | (2) |
|
Setting up and defining routes with URL parameters |
|
|
308 | (2) |
|
Using URL parameters in components and services |
|
|
310 | (4) |
|
Passing data to the Details page component |
|
|
314 | (1) |
|
Building the Details page view |
|
|
315 | (6) |
|
10.2 Working with forms and handling submitted data |
|
|
321 | (10) |
|
Creating the review form in Angular |
|
|
321 | (4) |
|
Sending submitted form data to an API |
|
|
325 | (6) |
|
10.3 Improving the architecture |
|
|
331 | (7) |
|
Using a separate routing-configuration file |
|
|
331 | (3) |
|
Improving the location class definition |
|
|
334 | (4) |
|
10.4 Using the SPA instead of the server-side application |
|
|
338 | (5) |
|
Routing Express requests to the build folder |
|
|
339 | (1) |
|
Making sure that deep URLs work |
|
|
340 | (3) |
|
Part 4 Managing authentication and user sessions |
|
|
343 | (52) |
|
11 Authenticating users, managing sessions, and securing APIs |
|
|
345 | (26) |
|
11.1 How to approach authentication in the MEAN stack |
|
|
346 | (4) |
|
Traditional server-based application approach |
|
|
346 | (2) |
|
Using the traditional approach in the MEAN stack |
|
|
348 | (1) |
|
|
348 | (2) |
|
11.2 Creating a user schema for MongoDB |
|
|
350 | (7) |
|
One-way password encryption: Hashes and salts |
|
|
350 | (1) |
|
Building the Mongoose schema |
|
|
351 | (1) |
|
|
351 | (1) |
|
Setting encrypted paths using Mongoose methods |
|
|
352 | (1) |
|
Validating a submitted password |
|
|
353 | (1) |
|
Generating a JSON Web Token |
|
|
354 | (3) |
|
11.3 Creating an authentication API with Passport |
|
|
357 | (7) |
|
Installing and configuring Passport |
|
|
357 | (3) |
|
Creating API endpoints to return JWTs |
|
|
360 | (4) |
|
11.4 Securing relevant API endpoints |
|
|
364 | (7) |
|
Adding authentication middleware to Express routes |
|
|
365 | (2) |
|
Using the JWT information inside a controller |
|
|
367 | (4) |
|
12 Using an authentication API in Angular applications |
|
|
371 | (24) |
|
12.1 Creating an Angular authentication service |
|
|
371 | (7) |
|
Managing a user session in Angular |
|
|
372 | (1) |
|
Allowing users to sign up, sign in, and sign out |
|
|
373 | (3) |
|
Using the JWT data in the Angular service |
|
|
376 | (2) |
|
12.2 Creating the Register and Login pages |
|
|
378 | (7) |
|
Building the Register page |
|
|
379 | (3) |
|
|
382 | (3) |
|
12.3 Working with authentication in the Angular app |
|
|
385 | (10) |
|
|
385 | (1) |
|
Adding a right-side section to the navigation |
|
|
385 | (10) |
Appendix A Installing the stack |
|
395 | (4) |
Appendix B Installing and preparing the supporting cast |
|
399 | (6) |
Appendix C Dealing with all of the views |
|
405 | (8) |
Appendix D Reintroducing JavaScript |
|
413 | (54) |
Index |
|
467 | |