Search Tutorials


Ecommerce Website - Online Book Store - Create User Admin Module - Part 2 | JavaInUse
     
 

   
   

Ecommerce Website - Online Book Store - Create User Admin Module - Part 2

In this tutorial series we will be developing an ecommerce website for buying books. In a previous tutorial we created the users module to list the existing users. In this tutorial we will be creating the add users component for adding new users.

Ecommerce Website - Online Book Store using Angular 8 + Spring Boot

Ecommerce Website - Online Book Store using Angular 8 + Spring Boot Introduction Ecommerce Website - Online Book Store - Create Menu Module Ecommerce Website - Online Book Store - Create User Admin Module - Part 1 Ecommerce Website - Online Book Store - Create User Admin Module - Part 2 Ecommerce Website - Online Book Store - Create User Admin Module - Part 3 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 1 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 2 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 3 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 4 Ecommerce Website - Online Book Store - Create Book Shopping Module

Video

This tutorial is explained in the below Youtube Video.

Spring Boot Application

We will be modifying the Spring Boot Application we had created in the previous tutorial. Modify the UserController class to add a method for saving the User.
package com.javainuse.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.javainuse.db.UserRepository;
import com.javainuse.model.User;

@RestController
@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping(path = "users")
public class UserController {

	@Autowired
	private UserRepository userRepository;
	
	@GetMapping("/get")
	public List<User> getUsers() {
		return userRepository.findAll();
	}
	
	@PostMapping("/add")
	public void createUser(@RequestBody User user) {
		userRepository.save(user);
	}

}

Angular Code

The page Structure for the User-Admin Page is as follows-

The Users Component will be having two child components - Add User Component and View User Component.

In this tutorial we will be implementing the add user component. Create a new component named add user.
ng generate component admin/users/adduser


We want the add user page to be displayed on the same page as the list users page. What we want is based on the url parameter either the add user page should get displayed  or the user details page. So whenever we will load the users component we will also be checking the url component  
  •  if the url has action=add then the adduser page will be displayed.  
  • If the url has the  action=view then the view user page will be displayed.  
  • if no action parameter is present  then neither the add user page or the view user page will be displayed.
Modify the Users component as follows -  
  • In the constructor add the activatedRoute and router.
    • ActivatedRoute - Gives us access to the current route instance.
    • Router - using this we can navigate to another page.
  • In the ngOnInit function  we will be  using the ActivatedRoute to get the current route parameters. We will be checking if it contains the action parameter  
  • Implement the addUser function. In this function using the Router we will be  again navigating to the same page - /admin/users,  but with additional parameters of action=add.
import { Component, OnInit } from '@angular/core';
import { User } from '../../model/User';
import { HttpClientService } from '../../service/http-client.service';
import { ActivatedRoute, Router } from '@angular/router';


@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {

  users: Array<User>;
  selectedUser: User;
  action: string;

  constructor(private httpClientService: HttpClientService,
    private router: Router,
    private activatedRoute: ActivatedRoute) { }

  ngOnInit() {
    this.httpClientService.getUsers().subscribe(
      response => this.handleSuccessfulResponse(response),
    );

    this.activatedRoute.queryParams.subscribe(
      (params) => {
        this.action = params['action']
      }
    );
  }

  handleSuccessfulResponse(response) {
    this.users = response;
  }

  addUser() {
    this.selectedUser = new User();
    this.router.navigate(['admin', 'users'], { queryParams: { action: 'add' } });
  }

}
In case of add user we will be adding a button in the users page.   For displaying the addusers page in the users page we will be making use of the selector tag of the add user component. We will be showing the add users page only when we have the action parameter as add.  Also we will be specifying the user as selectedUser which will be passed as input to the add user component.
   



<h1>Users Admin</h1>
<a class="btn btn-primary mb-3" (click)="addUser()">add</a>
<div class="container row">
    <div   class="col-md-6">
    <table class="table">
      <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th></th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let user of users" >
        <td>{{user.id}}</td>
        <td>{{user.name}}</td>
        <td><button type="button" class="btn btn-primary">Show Details</button></td>
      </tr>
      </tbody>
    </table>
  </div>
  <div   class="col-md-6">
      <app-adduser *ngIf="action === 'add'"  [user]="selectedUser"></app-adduser>
  </div>
</div>
Also we want to pass the new user that we have created to the child component i.e add user component.  We achieve this using the input tag.    

Finally in the add-users component we create the User named user and decorate it with the Input annotation. This specifies that the user instance will be provided by the parent component to the add user child component whenever it gets called.
import { Component, OnInit, Input } from '@angular/core';
import { User } from '../../../model/User';

@Component({
  selector: 'app-adduser',
  templateUrl: './adduser.component.html',
  styleUrls: ['./adduser.component.css']
})
export class AdduserComponent implements OnInit {

  @Input()
  user: User

  constructor() { }

  ngOnInit() {
  }

}
Let us now start the application and goto the users page. Here we can see the list as follows-

Click on the Add button. We can see that the url has changed with the parameter action=add and also the add user page can now be seen.

Next we will be modifying the Add User Component to take user details and call the spring boot Backend to save the new user.
Modify the addUser html page to take new user parameters as follows-
<h1>Add User</h1>
<form #recievedUser="ngForm">

  <label for="name">Name</label>
  <input type="text" class="form-control" id="name" placeholder="user name" [(ngModel)]="user.name" name="name">

  <label for="type">Type</label>
  <input type="text" class="form-control" id="type" placeholder="type name" [(ngModel)]="user.type" name="name">

  <label for="password">Password</label>
  <input type="password" class="form-control" id="password" placeholder="password" [(ngModel)]="user.password" name="password">

   <br>
  <button type="button" class="btn btn-success" (click)="addUser()">Save</button>
</form>
As we are using the ng model and ng form we will need to include the FormsModule in the app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms';


import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
import { FooterComponent } from './footer/footer.component';
import { UsersComponent } from './admin/users/users.component';
import { HttpClientModule } from '@angular/common/http';
import { AdduserComponent } from './admin/users/adduser/adduser.component';


@NgModule({
  declarations: [
    AppComponent,
    MenuComponent,
    FooterComponent,
    UsersComponent,
    AdduserComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Next in the HttpClientService we will be adding the addUser method. This method will be making a POST call to Spring backend to save the user.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from '../model/User';


@Injectable({
  providedIn: 'root'
})
export class HttpClientService {

  constructor(private httpClient: HttpClient) {
  }

  getUsers() {
    console.log('Getting all users');
    return this.httpClient.get<User[]>('http://localhost:8080/users/get');
  }

  addUser(newUser: User) {
    return this.httpClient.post<User>('http://localhost:8080/users/add', newUser);   
  }
}
Next we will be modifying the add user component typescript file -
  • In the constructor add the HttpClientService and the Router
  • Define the addUser function to add new user
import { Component, OnInit, Input, Output } from '@angular/core';
import { User } from '../../../model/User';
import { HttpClientService } from '../../../service/http-client.service';
import { Router } from '@angular/router';


@Component({
  selector: 'app-adduser',
  templateUrl: './adduser.component.html',
  styleUrls: ['./adduser.component.css']
})
export class AdduserComponent implements OnInit {

  @Input()
  user: User

 constructor(private httpClientService: HttpClientService,
    private router: Router) { }

  ngOnInit() {
  }

  addUser() {
    this.httpClientService.addUser(this.user).subscribe(
      (user) => {
        this.router.navigate(['admin', 'users']);
      }
    );
  }
}
If we now run the application Navigate to the add page -

enter the details and click on save

We can see that the list users is still not showing the added user.
If we refresh the users page then we can see the new user.

If we check the database we can see that new user has been added.

So we need to tell the parent users component that child add user component has added a new User so fetch the users list again. We do this using the Output annotation.

In the add users component file add the Eventemitter. Also if the user is successfully added then we send a signal to the parent users component.
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { User } from '../../../model/User';
import { HttpClientService } from '../../../service/http-client.service';
import { Router } from '@angular/router';


@Component({
  selector: 'app-adduser',
  templateUrl: './adduser.component.html',
  styleUrls: ['./adduser.component.css']
})
export class AdduserComponent implements OnInit {

  @Input()
  user: User

  @Output()
  userAddedEvent = new EventEmitter();

  newUser: User;
  message: string;
  password: string;

  constructor(private httpClientService: HttpClientService,
    private router: Router) { }

  ngOnInit() {
    this.newUser = Object.assign({}, this.user);

  }

  addUser() {
    this.httpClientService.addUser(this.newUser).subscribe(
      (user) => {
        this.userAddedEvent.emit();
        this.router.navigate(['admin', 'users']);
      }
    );
  }
}
In the users component we specify the function to be called on userAddedEvent.
<h1>Users Admin</h1>
<a class="btn btn-primary mb-3" (click)="addUser()">add</a>
<div class="container row">
  <div class="col-md-6">
    <table class="table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let user of users">
          <td>{{user.id}}</td>
          <td>{{user.name}}</td>
          <td><button type="button" class="btn btn-primary">Show Details</button></td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="col-md-6">
    <app-adduser *ngIf="action === 'add'" [user]="selectedUser" (userAddedEvent)="refreshData()"></app-adduser>
  </div>
</div>
Finally in the users component we define the refreshData function. This function will fetch the user list from the Spring Boot Application.
import { Component, OnInit } from '@angular/core';
import { User } from '../../model/User';
import { HttpClientService } from '../../service/http-client.service';
import { ActivatedRoute, Router } from '@angular/router';


@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {

  users: Array<User>;
  selectedUser: User;
  action: string;

  constructor(private httpClientService: HttpClientService,
    private router: Router,
    private activatedRoute: ActivatedRoute) { }

  ngOnInit() {
   this.refreshData();
  }

  refreshData() {
    this.httpClientService.getUsers().subscribe(
      response => this.handleSuccessfulResponse(response),
    );

    this.activatedRoute.queryParams.subscribe(
      (params) => {
        this.action = params['action']
      }
    );
  }

  handleSuccessfulResponse(response) {
    this.users = response;
    console.log(this.users);
  }

  addUser() {
    this.selectedUser = new User();
    this.router.navigate(['admin', 'users'], { queryParams: { action: 'add' } });
  }

}
Now if we go to localhost:4200/admin/users and add a new user-

The new user gets immediately reflected in the users list.

Download Source Code

Download it -
Spring Boot + Ecommerce
Angular8 Online Book Store

 

See Also

Spring Boot Hello World Application- Create simple controller and jsp view using Maven Spring Boot Tutorial-Spring Data JPA Spring Boot + Simple Security Configuration Pagination using Spring Boot Simple Example Spring Boot + ActiveMQ Hello world Example Spring Boot + Swagger Example Hello World Example Spring Boot + Swagger- Understanding the various Swagger Annotations Spring Boot Main Menu Spring Boot Interview Questions