My react app successfully gets and posts from/to Spring Boot JPA MySql db. But delete fails with 404, meaning it can find the endpoint.
MedaverterApplication.java
@SpringBootApplication
@ComponentScan(basePackages = { "net.tekknow.medaverter.*" })
@EntityScan(basePackages = "net.tekknow.medaverter.*")
public class MedaverterApplication {
public static void main(String[] args) {
SpringApplication.run(MedaverterApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true);
}
};
}
}
EventController.java
package net.tekknow.medaverter.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.util.List;
import net.tekknow.medaverter.models.Event;
import net.tekknow.medaverter.repository.EventRepo;
@CrossOrigin
@RestController
public class EventController {
@Autowired
EventRepo eventRepo;
@GetMapping("/get-events")
public List<Event> getEvents(int user_id) {
List<Event> events = eventRepo.findEventsByUserId(user_id);
return events;
}
@PostMapping(path = "/save-event", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<Event> addEvent(@RequestBody Event event) {
return ResponseEntity.ok().body(eventRepo.save(event));
}
@DeleteMapping("/delete-event/{id}")
public ResponseEntity<String> deleteEvent(@PathVariable Integer id) {
try {
eventRepo.deleteById(id);
return new ResponseEntity<>("Item deleted successfully", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>("Error deleting item", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Note that both GET and POST work, but not DELETE
events.tsx
const deleteEvent = async (id: GridRowId) => {
const response = await fetch(`/delete-event?id=${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json' // Or the appropriate content type
},
})
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
console.log('Row deleted successfully:', data);
})
.catch((error) => {
console.error('Error deleting row:', error);
});
}
I also tried:
const response = await fetch(`http://localhost:3000/delete-event?id=${id}`, {...
const response = await fetch(`http://localhost:8080/delete-event?id=${id}`, {...
How is it that I can get and save data, but not delete? I thought maybe the browser was blocking due to CORS, but I've got that covered. Can anybody see what I am doing wrong?
You have a mismatch in the endpoint. Your backend controller expects "/delete-event/{id}" which means a path variable. But from frontend side, you are calling the API via query parameter like /delete-event?id=${id}
.
The correct way should be:
const deleteEvent = async (id: GridRowId) => {
await fetch(`/delete-event/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => {
console.log('Row deleted successfully:', data);
})
.catch((error) => {
console.error('Error deleting row:', error);
});
};
Now your frontend will call the /delete-event/${id}
properly. This matches the @DeleteMapping("/delete-event/{id}")
.