In the previous part of the Angular blog tutorial series, you learnt how to create the ShowPostComponent
to display the list of blog posts on the home page. You fetched the records that were inserted from the MongoDB shell using the created REST API endpoint.
In this tutorial, you’ll be creating a new component called AddPostComponent
to provide the user interface to add a new blog post to the MongoDB database.
Getting Started
Let’s get started by cloning the source code from the previous part of the tutorial series.
git clone https://github.com/royagasthyan/ShowPost AddPost
Navigate to the project directory and install the required dependencies.
cd AddPost/client npm install cd AddPost/server npm install
Once you have the dependencies installed, restart the client and server application.
cd AddPost/client npm start cd AddPost/server node app.js
Point your browser to http://localhost:4200 and you should have the application running.
Creating the Add Post Component
Let’s get started by creating the AddPostComponent
. Create a folder called add-post
inside the src/app
folder. Inside the add-post
folder, create a file called add-post.component.ts
and add the following code:
import { Component } from '@angular/core'; import { Post } from '../models/post.model'; @Component({ selector: 'app-add-post', templateUrl: './add-post.component.html', styleUrls: ['./add-post.component.css'] }) export class AddPostComponent { constructor() { } }
Create a file called add-post.component.html
and the following HTML code:
You’ll be showing the add post component as a popup.
Now you need to add the AddPostComponent
to the NgModule
. Import the AddPostComponent
in the app.module.ts
file.
import { AddPostComponent } from './add-post/add-post.component';
Add the component to the NgModule
declarations
list. Here is how it looks:
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'; import { ShowPostComponent } from './show-post/show-post.component'; import { AddPostComponent } from './add-post/add-post.component'; @NgModule({ declarations: [ RootComponent, LoginComponent, HomeComponent, ShowPostComponent, AddPostComponent ], imports: [ BrowserModule, ROUTING, FormsModule, HttpClientModule ], providers: [], bootstrap: [RootComponent] }) export class AppModule { }
To trigger the add post popup, you have already added the data-target
attribute to the button in home.component.html
.
Save the above changes and restart the application. Log into the application and click on the Add link in the home page. You will have the AddPostComponent
displayed as a popup.
Implementing the Add Post Functionality
Add the ngModel
directive to the input elements for title
and description
.
Add a click
directive to the button for calling the method to save the blog post.
Import the Post
model from src/app/models/post.model.ts
in the add-post.component.ts
file.
import { Post } from '../models/post.model';
Define the post
variable in the add-post.component.ts
file.
public post : Post;
Define the addPost
method inside the add-post.component.ts
file. From the addPost
method, you’ll validate the entered title
and description
and make a call to the service method to call the REST API. Here is how the method looks:
addPost() { if(this.post.title && this.post.description){ // call the service method to add post } else { alert('Title and Description required'); } }
Let’s create the service file for the component AddPostComponent
. Create a file called add-post.service.ts
and add the following code:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Post } from '../models/post.model'; @Injectable() export class AddPostService { constructor(private http: HttpClient){ } }
Inside the AddPostService
, create a method called addPost
to make the REST API call.
addPost(post: Post){ return this.http.post('/api/post/createPost',{ title : post.title, description : post.description }) }
As seen in the above code, you have made use of the HttpClient
to make the API call and return the Observable
.
In the add-post.component.ts
file inside the addPost
method, you’ll subscribe to the addPost
method from the add-post.service.ts
file.
this.addPostService.addPost(this.post).subscribe(res =>{ // response from REST API call });
Here is how the add-post.component.ts
file looks:
import { Component } from '@angular/core'; import { AddPostService } from './add-post.service'; import { Post } from '../models/post.model'; @Component({ selector: 'app-add-post', templateUrl: './add-post.component.html', styleUrls: ['./add-post.component.css'], providers: [ AddPostService ] }) export class AddPostComponent { public post : Post; constructor(private addPostService: AddPostService) { this.post = new Post(); } addPost() { if(this.post.title && this.post.description){ this.addPostService.addPost(this.post).subscribe(res =>{ console.log('response is ', res) }); } else { alert('Title and Description required'); } } }
Creating the REST API for Add Post
Let’s create a REST API end point for adding the blog post to the MongoDB database. In the server/app.js
file, create an API end point as shown:
app.post('/api/post/createPost', (req, res) => { // insert the details to MongoDB })
First, you need to connect to the MongoDB database using the Mongoose
client.
mongoose.connect(url, { useMongoClient: true }, function(err){ if(err) throw err; console.log('connection established '); });
Once the connection has been established, you need to create a model object using the Post
schema defined in the server/model/post.js
file.
const post = new Post({ title: req.body.title, description: req.body.description })
As seen in the above code, you created the Post object using the title
and description
passed in from the request req
object.
Call the save
method on the Post object to save the entry to MongoDB.
post.save((err, doc) => { if(err) throw err; return res.status(200).json({ status: 'success', data: doc }) })
As seen in the above code, once the save
method callback is called with no error, it will return the success
message along with the returned object doc
.
Here is how the REST API end point finally looks:
app.post('/api/post/createPost', (req, res) => { mongoose.connect(url, { useMongoClient: true }, function(err){ if(err) throw err; const post = new Post({ title: req.body.title, description: req.body.description }) post.save((err, doc) => { if(err) throw err; return res.status(200).json({ status: 'success', data: doc }) }) }); })
Save the above changes and restart both Angular and Node servers. Sign in to the application and try to add a new blog post. Once you click on the Add button, check the browser console and you will have the success response logged.
When the blog post details are added to the database successfully, you need to close the popup. In order to close the popup, there is a close button which you need to click programmatically.
You’ll be using the @ViewChild
decorator to access the close button.
Import ViewChild
and ElementRef
in AddPostComponent
.
import { Component, ViewChild, ElementRef } from '@angular/core';
Inside the AddPostComponent
, define the following variable:
@ViewChild('closeBtn') closeBtn: ElementRef;
Initiate the closeBtn
click using the following code:
this.closeBtn.nativeElement.click();
Add the above code to the success callback of the addPost
method. Here is the addPost
method from add-post.component.ts
.
addPost() { if(this.post.title && this.post.description){ this.addPostService.addPost(this.post).subscribe(res =>{ this.closeBtn.nativeElement.click(); }); } else { alert('Title and Description required'); } }
Save the changes and restart the client server. Log into the application and try adding a new blog post. Once the blog post details have been saved successfully, the popup will close.
Refreshing the Blog List
One thing to note is that the newly added blog post doesn’t show up in the blog post list. So you need to add a trigger to notify when to update the ShowPostComponent
. You’ll be making use of a common service to communicate between the two components.
Create a folder called service
inside the src/app
folder. Create a file called common.service.ts
with the following code:
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable() export class CommonService { public postAdded_Observable = new Subject(); constructor(){ } notifyPostAddition(){ this.postAdded_Observable.next(); } }
As seen in the above code, you have declared a Subject
called postAdded_Observable
to keep track of the new blog post addition to the database. Whenever a new blog post is added to the database, you’ll call the notifyPostAddition
method, which will notify the subscribers about the update.
Import the CommonService
in app.module.ts
and include it in the NgModule
provider’s list. Here is how it looks:
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'; import { ShowPostComponent } from './show-post/show-post.component'; import { AddPostComponent } from './add-post/add-post.component'; import { CommonService } from './service/common.service'; @NgModule({ declarations: [ RootComponent, LoginComponent, HomeComponent, ShowPostComponent, AddPostComponent ], imports: [ BrowserModule, ROUTING, FormsModule, HttpClientModule ], providers: [CommonService], bootstrap: [RootComponent] }) export class AppModule { }
Import CommonService
in the show-post.component.ts
file and initialize it in the constructor method.
import { CommonService } from '../service/common.service';
constructor(private showPostService: ShowPostService, private commonService: CommonService) { }
Inside the ngOnInit
method, subscribe to the postAdded_Observable
variable and load the getAllPost
method. Here is how the ngOnInit
method looks:
ngOnInit(){ this.getAllPost(); this.commonService.postAdded_Observable.subscribe(res => { this.getAllPost(); }); }
Import CommonService
in the add-post.component.ts
file and call the notifyPostAddition
method once the blog post has been added. Here is how the addPost
method from the AddPostComponent
looks:
addPost() { if(this.post.title && this.post.description){ this.addPostService.addPost(this.post).subscribe(res =>{ this.closeBtn.nativeElement.click(); this.commonService.notifyPostAddition(); }); } else { alert('Title and Description required'); } }
Save the above changes and restart the client server. Log in to the application and add a new blog post. Once added, the blog post list gets updated with the new blog post.
Wrapping It Up
In this tutorial, you created the AddPostComponent
to add the blog post details to the MongoDB database. You created the REST API for saving a blog post to the MongoDB database using the Mongoose
client.
In the next part of the series, you’ll implement the functionality to edit and update the blog post details.
Source code for this tutorial is available on GitHub.
How was your experience so far? Do let me know your valuable suggestions in the comments below.
Powered by WPeMatico