skip to Main Content

I’m getting 405 in console, when I send PUT request.

Here is my ajax call, which is part of bigger function:

triggerPutRequest(id, stringDate, isDone, title)
                .then((data) => {
                    console.log(data);
                })
                .catch((error) => {
                    alert(error);
                });


function triggerPutRequest(isDone, id, stringDate, title) {
    
        return new Promise((resolve, reject) => {
    
            $.ajax({
                type: 'PUT',  // http method
                url: window.location + "api/tasks", //endpoint on our backend
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                data: JSON.stringify({
                    "id": id,
                    "title": title,
                    "dueDate":  convertDateToString(new Date(datepicker.value)),
                    "done": isDone,                                         
                }),
    
                success: function (data) {
                    resolve(data)
                },
                error: function () {
                    reject("string")
                }
            });
    
        })
    
    }

In my Spring Boot I have simple Task model object with omitted unrelevant fields:

public class Task {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", unique = true, nullable = false)
        private int id;

        @Column(name = "due_date", unique = false, nullable = false)
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
        private LocalDate dueDate;

        @NotEmpty(message = "cannot be empty string")
        @Column(name = "title", unique = true, nullable = false)
        private String title;
    
        @Column(name = "done", unique = false, nullable = false)
        private boolean done;
}

My controller class in Spring Boot and endpoint method for updating look like this:

@RestController
@RequestMapping(value="/api/tasks")

public class TaskController {
    @PutMapping(value="/", consumes="application/json")
    public ResponseEntity<Task> updateTask(@RequestBody Task taskToBeUpdated){
        //update object logic
        return new ResponseEntity<Task>(newlyAddedTask, HttpStatus.OK);
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    Ahh...and here is the bug..

    In my class I had this:

    public class Task {
    
      ...
    
        @Column(name = "due_date", unique = false, nullable = false)
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
        private LocalDate dueDate;
    
        ...
    

    }

    Somehow, I manged to post correct way here in SO, but in my code it was wrong...I dont't know how I pull this off..day and a half just wasted.

    Regarding Thomas's answer..Doesn't that sounds a bit redundant to do that extra step? If I have all the data from the object I need while doing editing of an object? Why I cant just take that object as a placeholder for new values. Then from db, just take object with same id and set new variables...


  2. Your problem is this:

    Could not resolve parameter [0] in public org.springframework.http.ResponseEntity<com.marbleit.todo.model.Task> com.marbleit.todo.controllers.TaskController.updateTask; HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type int from String "20-08-2020": not a valid Integer
    

    The first value you are sending in is a string and you are trying to place it into an int. So you should print the requestbody from the client.

    You have mixed up the variable order in your code:

    triggerPutRequest(id, stringDate, ...
    
    function triggerPutRequest(isDone, id, ...
    
    

    Also.

    It is common practice to keep the api against the client separated from the api against the database.

    So what does this mean? Well it means that if you would for example change something in the database it would now have a ripple effect out to the client since you are serializing/deserializing straight into the database entity. This makes the client tightly coupled with the database.

    So you should avoid taking data from the client and put it straight into your database entity and instead have a intermittent object for instanse a TaskRequest. Then from this take the data and place into your entity so both the client api and the database api can evolve independently from eachother.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search