2

I am making a rest API using spring to do crud operations. In my angular app, the delete HTTP client is not working, when I click the delete button the selected id is not deleted. I know my server is running and the controller code is correct.

This is Employee-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Employee } from '../employee' ;
import { EmployeeService } from '../employee.service';
@Component({
  selector: 'app-employee-list',
  templateUrl: './employee-list.component.html',
  styleUrls: ['./employee-list.component.css']
})

export class EmployeeListComponent implements OnInit {


  employees!: Employee[]; 
 
  constructor(private employeeService : EmployeeService ,
    private router : Router) { }

  ngOnInit(): void {

      this.fetchEmployees();
  }
  private fetchEmployees()
  {
    
    this.employeeService.getEmployeesList().subscribe(data => this.employees = data );
  }

  updateEmployee(id : number)
  {
    this.router.navigate(['update-employee' , id ]) ;
  }
  deleteEmployee(id : number)
  {
    this.employeeService.deleteEmployee(id).subscribe(data => {
      
      this.fetchEmployees() ;
    })
  }

}

And this is services page - employee.service.ts

import { Injectable } from '@angular/core';
import { HttpClient} from '@angular/common/http' ;
import { Observable } from 'rxjs';
import { Employee } from './employee';

/** Injectable - means it will be used to provide services  */
@Injectable({
  providedIn: 'root'
})
export class EmployeeService {

   private baseUrl = "http://localhost:8080/api/v1/employees" ;


   constructor(private httpClient: HttpClient) { }

   getEmployeesList() : Observable<Employee[]>
   {
     return this.httpClient.get<Employee[]>(`${this.baseUrl}`) ; 
     
   }

   createEmployee(employee : Employee) : Observable<Object>{
     return this.httpClient.post(`${this.baseUrl}` , employee) ;
   } 

   
  getEmployeeById(id: number): Observable<Employee>{
    return this.httpClient.get<Employee>(`${this.baseUrl}/${id}`);
  }
   updateEmployee(id: number, employee: Employee): Observable<Object>{
    return this.httpClient.put(`${this.baseUrl}/${id}`, employee);
  }

  deleteEmployee(id:number ) : Observable<Object>{
    return this.httpClient.delete(`${this.baseUrl}/${id}` ) ;
  
}}

And here is how the button is bound to the deleteEmployee() in employee-list.component.html

  <button (click) = "deleteEmployee(employee.id)" class = "btn btn-danger" style="margin-left: 10px"> Delete</button>

Error is

Access to XMLHttpRequest at 'http://localhost:8080/api/v1/employees/1' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

zone.js:2863 DELETE http://localhost:8080/api/v1/employees/1 net::ERR_FAILED

But i have added cross origin works fine for get , post and put request .PLease help.

And this is EmployeeController

package net.javaguides.springboot.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.javaguides.springboot.repository.EmployeeRepository ;
import net.javaguides.springboot.exception.ResourceNotFoundException;
import net.javaguides.springboot.model.Employee ;

@CrossOrigin(origins = "http://localhost:4200") 
@RestController
@RequestMapping("/api/v1/")
public class EmployeeController {
    
    
    @Autowired
    private EmployeeRepository  employeeRepository ;
    
    //get all employees
    @GetMapping("/employees")
    public List<Employee> getAllEmployees()
    {
        return employeeRepository.findAll() ;
    }
    
    //create employee api 
    @PostMapping("/employees")
    public Employee createEmployee(@RequestBody Employee employee)
    {
        return employeeRepository.save(employee);
    }
    
    // get employee by id rest api
    @GetMapping("/employees/{id}")
    public ResponseEntity<Employee> getEmployeeById(@PathVariable Long id) 
    {
        
        Employee employee = employeeRepository
                            .findById(id)
                            .orElseThrow(()-> new ResourceNotFoundException("Employee not exist with id : " + id));
        
        return ResponseEntity.ok(employee) ;
    }
    
    //update employee rest api
    @PutMapping("/employees/{id}")
    public ResponseEntity<Employee> updateEmployee(@PathVariable Long id ,@RequestBody Employee empdetails)
    {
        Employee employee = employeeRepository
                .findById(id)
                .orElseThrow(()-> new ResourceNotFoundException("Employee not exist with id : " + id));
    employee.setFirstName(empdetails.getFirstName());
    employee.setLastName(empdetails.getLastName());
    employee.setEmailId(empdetails.getEmailId());
    
    Employee updatedEmployee =employeeRepository.save(employee);
    return ResponseEntity.ok(updatedEmployee) ;
    }
    
    //delete employee rest api
    @DeleteMapping("/employees/{id")
    public ResponseEntity<Map<String, Boolean>> deleteEmployee(@PathVariable Long id ,@RequestBody Employee empdetails)
    {
        Employee employee = employeeRepository
                .findById(id)
                .orElseThrow(()-> new ResourceNotFoundException("Employee not exist with id : " + id));
        
        employeeRepository.delete(employee);
        Map<String, Boolean> response = new HashMap<>();
        response.put("deleted", Boolean.TRUE);
        return ResponseEntity.ok(response);
    }

}

Help is appreciated . I am stuck on this part from yesterday .

  • 2
    You need to show the contents of `employee-list.component.html`. There is no way, at the moment, to know how the button in the template is bound to the `deleteEmployee()` function. – ruth Jul 22 '21 at 09:47
  • 1
    When you check the network tab of your browser's development console, what is the server's answer to the `DELETE` request? – CGundlach Jul 22 '21 at 11:22
  • You should inspect the HTTP requests in browser's developers tool window and update your findings. – S.D. Jul 22 '21 at 11:27
  • DELETE http://localhost:8080/api/v1/employees/1 net::ERR_FAILED – Aastha Singh Jul 22 '21 at 11:27
  • 2
    _" i have added cross origin works fine for get , post and put request"_ But you are doing a `DELETE` ... – Gaël J Jul 22 '21 at 11:38
  • yes i have added delete method but cors is not allowing it – Aastha Singh Jul 22 '21 at 11:39
  • Could you share your server configuration where you set up CORS? Also, if you execute the request outside of the web browser (e.g. with the tool Postman or the PowerShell CmdLet `Invoke-RestMethod`), does it work? If so, what headers are returned in the call? – CGundlach Jul 22 '21 at 11:41
  • 1
    I am new to this so I do not understand where to put server configuration in spring boot. I have put cross-origin in my controller file. I will share that with you. I am new so please do not judge. – Aastha Singh Jul 22 '21 at 11:54
  • 1
    "I am new so please do not judge" We all were at some point. Don't worry :) The issue seems twofold: 1) You seem to be missing a `}` in the mapping of the `DELETE` handler, which likely means that the called address is never reached 2) It seems that Spring Boot needs additional configuration to return error messages with the proper CORS headers, which is why you're getting a CORS error and not a 404 here - see here on how to possibly fix that: https://stackoverflow.com/questions/35091524/spring-cors-no-access-control-allow-origin-header-is-present/35092082#35092082 – CGundlach Jul 22 '21 at 12:06

2 Answers2

1

The problem is, your Rest API(Java) expects a request body and your client(Angular Code) is not sending one.

Change one of these

  1. Either remove @RequestBody Employee empdetails from controller signature like shown below.
//delete employee rest api
@DeleteMapping("/employees/{id")
public ResponseEntity<Map<String, Boolean>> deleteEmployee(@PathVariable Long id)
  1. Or Add employee details in the request body of http delete like this
deleteEmployee(id:number, employee : Employee) : Observable<Object> {
    return this.httpClient.delete(`${this.baseUrl}/${id}`, employee);
}

naveen
  • 53,448
  • 46
  • 161
  • 251
0

Adding new package with configuration file , solved cross origin error

package net.javaguides.springboot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class Myconfiguration {

    @SuppressWarnings("deprecation")
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                .allowedMethods("GET" ,"POST" , "UPDATE" ,"PUT", "DELETE")
                .allowedOrigins("*")
                .allowedHeaders("*");
            }
        };
    }
}

And also I removed @RequestBody Employee empdetails from controller.

Thanks all .Its working .