typescript - Angular: Http delete fungerar inte i mitt fullstackprojekt med rest-api


Jag skapar ett REST-API med Spring för att utföra CRUD-operationer. I min Angular-app fungerar inte delete HTTP-klienten, när jag klickar på delete-knappen tas det valda ID:t inte bort. Jag vet att min server körs och att controller-koden är korrekt.

Detta är 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() ;
    })
  }

}

Och detta är services-sidan - 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}` ) ;
  
}}

Och här är hur knappen är bunden till deleteEmployee() i employee-list.component.html

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

Fel är

Åtkomst till XMLHttpRequest på 'http://localhost:8080/api/v1/employees/1' från ursprung 'http://localhost:4200' har blockerats av CORS-policy: Svar på preflight-förfrågan passerar inte åtkomstkontrollkontrollen: Ingen 'Access-Control-Allow-Origin'-header finns på den begärda resursen.

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

Men jag har lagt till cross origin, fungerar bra för GET-, POST- och PUT-förfrågningar. Snälla hjälp.

Och detta är 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);
    }

}

Hjälp uppskattas. Jag har fastnat på den här delen sedan igår.

Svar #1

Problemet är att din Rest API (Java) förväntar sig en begäransbody och din klient (Angular-kod) skickar ingen.

Byt ut en av dessa

  1. Ta antingen bort @RequestBody Employee empdetails från controller-signaturen som visas nedan.
//delete employee rest api
@DeleteMapping("/employees/{id")
public ResponseEntity<Map<String, Boolean>> deleteEmployee(@PathVariable Long id)
  1. Eller lägg till anställdas uppgifter i begärans kropp av http delete så här
deleteEmployee(id:number, employee : Employee) : Observable<Object> {
    return this.httpClient.delete(`${this.baseUrl}/${id}`, employee);
}

Svar #2

Lägger till nytt paket med konfigurationsfil, löste problem med korsursprung

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("*");
            }
        };
    }
}

Och jag tog också bort @RequestBody Employee empdetails från kontrollern.

Tack allihopa. Det fungerar.