Creating a Blogging App Using Angular & MongoDB: Home

In the first part of the tutorial series, you saw how to get started with creating an Angular web app. You learnt how to set up the application and created the Login component.

In this part of the series, you’ll move further and write down the REST API required for interacting with the MongoDB bank end. You’ll also create the Home component which will be displayed after the user has logged in successfully.

Getting Started

Let’s get started by cloning the source code from the first part of the tutorial series.

git clone https://github.com/royagasthyan/AngularBlogApp-Login AngularBlogApp-Home

Navigate to the project directory and install the required dependencies.

cd AngularBlogApp-Home/client
npm install

Once you have the dependencies installed, restart the application server.

npm start

Point your browser to http://localhost:4200 and you should have the application running.

Creating the Login REST API

Inside the project folder AngularBlogApp-Home, create another folder called server. You’ll be writing the REST APIs using Node.js.

Navigate to the server folder and initialize the project.

cd server
npm init

Enter the required details and you should have the project initialized.

You’ll be using the Express framework for creating the server. Install Express using the following command:

npm install express --save

Once you have Express installed, create a file called app.js. This will be the root file for your Node.js server.

Here is how the app.js file looks:

const express = require('express')
const app = express()

app.get('/api/user/login', (req, res) => {
    res.send('Hello World!')
})

app.listen(3000, () => console.log('blog server running on port 3000!'))

As seen in the above code, you imported express into app.js. Using express, you created an application app.

Using app, you exposed an endpoint /api/user/login which will display a message. Start the Node.js server using the following command:

node app.js

Point your browser to http://localhost:3000/api/user/login and you should have the message displayed.

You’ll be making a POST request from the Angular service to the server with the username and password parameters. So you need to parse the request parameters.

Install body-parser, which is Node.js body-parsing middleware to parse request parameters.

npm install body-parser --save

Once you have it installed, import it in app.js .

const bodyParser = require('body-parser')

Add the following code to the app.js file.

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended : false}))

The above two body-parser options return the middleware that only parses json and urlencoded bodies and only looks at requests where the Content-Type header matches the type option.

You’ll be using Mongoose to interact with MongoDB from Node.js. So install Mongoose using Node Package Manager (npm).

npm install mongoose --save

Once you have mongoose installed, import it in app.js.

const mongoose = require('mongoose');

Define the MongoDB database URL in app.js.

const url = 'mongodb://localhost/blogDb';

Let’s use Mongoose to connect to the MongoDB database. Here is how it looks:

app.post('/api/user/login', (req, res) => {
    mongoose.connect(url, function(err){
		if(err) throw err;
		console.log('connected successfully, username is ',req.body.username,' password is ',req.body.password);
	});
})

If the connection is established, the message gets logged along with the username and password.

Here is how the app.js file looks:

const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const mongoose = require('mongoose');
const url = 'mongodb://localhost/blogDb';

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended : false}))

app.post('/api/user/login', (req, res) => {
    mongoose.connect(url, function(err){
    	if(err) throw err;
		console.log('connected successfully, username is ',req.body.username,' password is ',req.body.password);
	});
})

app.listen(3000, () => console.log('blog server running on port 3000!'))

Restart the Node server using the following command:

node app.js

To connect to the Node server from the Angular application, you need to set the proxy. Create a file called proxy.json inside the client/src folder. Here is how it looks:

{
    "/api/*": {
		"target": "http://localhost:3000",
		"secure": "false"
	}
}

Modify the client package.json file to start the application using the proxy file.

"start": "ng serve --proxy-config proxy.json"

Save the changes and start the client server.

npm start

Point your browser to http://localhost:4200 and enter the username and password. Click the sign in button and you should have the parameters logged in the Node console.

Validating the User Login

To interact with MongoDB using Mongoose, you need to define a schema and create a model. Inside the server folder, create a folder called model.

Create a file called user.js inside the model folder. Add the following code to the user.js file:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// create a schema
const userSchema = new Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  name: { type: String }
}, { collection : 'user' });

const User = mongoose.model('User', userSchema);

module.exports = User;

As seen in the above code, you imported mongoose into user.js. You created a userSchema using the mongoose schema and created the User model using the mongoose model.

Import the user.js file inside the app.js file.

const User = require('./model/user');

Before querying the MongoDB user collection, you need to create the collection. Go to the MongoDB shell by typing mongo. Create the collection user using the following command:

db.createCollection('user')

Insert a record which you’ll be querying against.

 db.user.insert({
     name: 'roy agasthyan',
     username: 'roy',
     password: '123'
 })

Now, once mongoose gets connected to MongoDB, you’ll find the record from the database using the username and password passed in. Here is how the API looks:

app.post('/api/user/login', (req, res) => {
    mongoose.connect(url,{ useMongoClient: true }, function(err){
		if(err) throw err;
		User.find({
			username : req.body.username, password : req.body.password
		}, function(err, user){
			if(err) throw err;
			if(user.length === 1){	
				return res.status(200).json({
					status: 'success',
					data: user
				})
			} else {
				return res.status(200).json({
					status: 'fail',
					message: 'Login Failed'
				})
			}
			
		})
	});
})

As seen in the above code, once you receive a response from the database, you return the same to the client side.

Save the above changes and try running the client and server. Enter the username as roy and password as 123 and you should be able to view the result in the browser console.

Redirecting to the Home Component

Once the user has been validated successfully, you need to redirect the user to the Home component. So let’s start by creating the Home component. 

Create a folder called Home inside the src/app folder. Create a file called home.component.html and add the following HTML code:

<header class="header clearfix">
    <nav>
        <ul class="nav nav-pills float-right">
            <li class="nav-item">
                <a class="nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Add</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Logout</a>
            </li>
        </ul>
    </nav>
    <h3 class="text-muted">Angular Blog App</h3>
</header>

<main role="main">

    <div class="jumbotron">
        <h1 class="display-3">Lorem ipsum</h1>
        <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
        <p><a class="btn btn-lg btn-success" href="#" role="button">Read More ...</a></p>
    </div>

    <div class="row marketing">
        <div class="col-lg-6">
            <h4>Subheading</h4>
            <p>Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.</p>

            <h4>Subheading</h4>
            <p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.</p>

            <h4>Subheading</h4>
            <p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
        </div>

        <div class="col-lg-6">
            <h4>Subheading</h4>
            <p>Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.</p>

            <h4>Subheading</h4>
            <p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.</p>

            <h4>Subheading</h4>
            <p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
        </div>
    </div>

</main>

<footer class="footer">
    <p>&copy; Company 2017</p>
</footer>

Create a file called home.component.css and add the following CSS style:

.header,
.marketing,
.footer {
  padding-right: 1rem;
  padding-left: 1rem;
}

/* Custom page header */
.header {
  padding-bottom: 1rem;
  border-bottom: .05rem solid #e5e5e5;
}

.header h3 {
  margin-top: 0;
  margin-bottom: 0;
  line-height: 3rem;
}

/* Custom page footer */
.footer {
  padding-top: 1.5rem;
  color: #777;
  border-top: .05rem solid #e5e5e5;
}

/* Customize container */
@media (min-width: 48em) {
  .container {
    max-width: 46rem;
  }
}
.container-narrow > hr {
  margin: 2rem 0;
}

/* Main marketing message and sign up button */
.jumbotron {
  text-align: center;
  border-bottom: .05rem solid #e5e5e5;
}
.jumbotron .btn {
  padding: .75rem 1.5rem;
  font-size: 1.5rem;
}

/* Supporting marketing content */
.marketing {
  margin: 3rem 0;
}
.marketing p + h4 {
  margin-top: 1.5rem;
}

/* Responsive: Portrait tablets and up */
@media screen and (min-width: 48em) {
  /* Remove the padding we set earlier */
  .header,
  .marketing,
  .footer {
    padding-right: 0;
    padding-left: 0;
  }

  /* Space out the masthead */
  .header {
    margin-bottom: 2rem;
  }

  .jumbotron {
    border-bottom: 0;
  }
}

Create the component file called home.component.ts and add the following code:

import { Component } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent {
  
}

As seen in the above code, you just created the HomeComponent using the @Component decorator and specifying the selector, templateUrl, and styleUrls

Add the HomeComponent to the NgModules in app.module.ts.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ROUTING } from './app.routing';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { RootComponent } from './root/root.component';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';


@NgModule({
  declarations: [
      RootComponent,
    LoginComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    ROUTING,
    FormsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [RootComponent]
})
export class AppModule { }

Import the HomeComponent in the app.routing.ts and define a route for home.

import { RouterModule, Routes } from '@angular/router';
import { ModuleWithProviders } from '@angular/core/src/metadata/ng_module';

import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';

export const AppRoutes: Routes = [
    { path: '', component: LoginComponent },
	{ path: 'home', component: HomeComponent }
];

export const ROUTING: ModuleWithProviders = RouterModule.forRoot(AppRoutes);

In the validateLogin method in the login.component.ts file, on successful validation redirect the user to the HomeComponent. To redirect, you need to import the Angular Router.

import { Router } from '@angular/router';

If the response from the API call is a success, you’ll navigate to the HomeComponent using the Angular Router.

if(result['status'] === 'success') {
  this.router.navigate(['/home']);
} else {
  alert('Wrong username password');
}

Here is how the login.component.ts file looks:

import { Component } from '@angular/core';
import { LoginService } from './login.service';
import { User } from '../models/user.model';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  providers: [ LoginService ]
})
export class LoginComponent {

  public user : User;

  constructor(private loginService: LoginService, private router: Router) {
      this.user = new User();
  }

  validateLogin() {
  	if(this.user.username && this.user.password) {
  		this.loginService.validateLogin(this.user).subscribe(result => {
        console.log('result is ', result);
        if(result['status'] === 'success') {
          this.router.navigate(['/home']);
        } else {
          alert('Wrong username password');
        }
        
      }, error => {
        console.log('error is ', error);
      });
  	} else {
  		alert('enter user name and password');
  	}
  }

}

Save the above changes and restart the server. Sign in to the application using the existing username and password, and you will be redirected to the HomeComponent.

Angular Blog App Home Component

Wrapping It Up

In this tutorial, you saw how to write the REST API endpoint for user sign-in. You learnt how to use Mongoose to interact with MongoDB from Node. After successful validation, you saw how to use Angular Router for navigating to the HomeComponent.

How was your experience learning to write an Angular application and its back end? Do let us know your thoughts and suggestions in the comments below.

Source code from this tutorial is available on GitHub.

You may also like...