JPA function doesn’t get access to REST @PutMapping url

Me, one professor and three from my project group haven’t been able to solve this, so I’m really hoping this works.

We are building a Spring Boot project with JPA and REST.

The output of createActivity() and updateActivity() is the same format and the REST functionality is nearly the same, so it doesn’t make sense to me that I get a 415 (Wrong mediatype) error, when calling the updateActivity() function.

The updateActivity() function works in Postman.

Debugging has concluded that it never receives the @PutMapping and I cannot for the life of me figure out why.

If you need anymore information, please say the word.

const title = document.getElementById("title-update");
const description = document.getElementById("description-update");
const price = document.getElementById("price-update");
const minHeight = document.getElementById("minHeight-update");
const minAge = document.getElementById("minAge-update");
const equipment = document.getElementById("equipment-update");
const imageLink = document.getElementById("imageLink-update");

function submitForm(){
    if (!event.preventDefault()) {
        createActivity();
    }
}

function createActivity() {

    let activity = {
            "title": document.getElementById("title").value,
            "description": document.getElementById("description").value,
            "price": document.getElementById("price").value,
            "minHeight": document.getElementById("minHeight").value,
            "minAge": document.getElementById("minAge").value,
            "equipment": document.getElementById("equipment").value,
            "imageLink": document.getElementById("imageLink").value,
        }
    console.log(activity);
    let body1 = JSON.stringify(activity);

    addActivity(body1)
}

function addActivity(body1) {
    const createActivityUrl = "http://localhost:8080/newActivity";

    const requestObject = {
            headers:{
                'Content-type': 'application/json',
            },
            method: 'POST',
            body: body1
        };

    console.log(body1);
    console.log(requestObject);

    fetch(createActivityUrl, requestObject)
        .then(response => response.json())
        .then(data => {
            console.log("Succes: ", data);
        })
        .then(alert("Aktiviteten er gemt"))
        .then(location.reload())
        .catch((error) =>{
            console.log("Error: ", error);
        })
}

let list = getAllActivities().then(x => list = x);

const dropdownAllActivities = document.getElementById("dropdownAllActivities");

async function getAllActivities() {
    const url = "http://localhost:8080/findAllActivities"
    const response = await fetch(url);
    const data = await response.json();

    dropdownAllActivities.length = 0;

    data.forEach(x => {
        let element = document.createElement("option");
        element.value = x.activityId;
        element.setAttribute('class', 'updateActivityClass');
        element.textContent = x.title;
        dropdownAllActivities.appendChild(element)
    })

    return data;
}

dropdownAllActivities.addEventListener('change', x => {
    title.value = list[dropdownAllActivities.selectedIndex].title;
    description.value = list[dropdownAllActivities.selectedIndex].description;
    price.value = list[dropdownAllActivities.selectedIndex].price;
    minHeight.value = list[dropdownAllActivities.selectedIndex].minHeight;
    minAge.value = list[dropdownAllActivities.selectedIndex].minAge;
    equipment.value = list[dropdownAllActivities.selectedIndex].equipment;
    imageLink.value = list[dropdownAllActivities.selectedIndex].imageLink;
});

function updateSubmit() {
    if(!event.preventDefault()) {
        updateActivity();
    }
}

function updateActivity() {

    let updatedActivity = {
        "activityId": list[dropdownAllActivities.selectedIndex].activityId,
        "description": document.getElementById("description-update").value,
        "equipment": document.getElementById("equipment-update").value,
        "imageLink": document.getElementById("imageLink-update").value,
        "minAge": document.getElementById("minAge-update").value,
        "minHeight": document.getElementById("minHeight-update").value,
        "price": document.getElementById("price-update").value,
        "title": document.getElementById("title-update").value
    }

    let updateActivityStringified = JSON.stringify(updatedActivity);

    updateDB(updateActivityStringified);
}

function updateDB(updateActivityStringified) {
    const putUrl = "http://localhost:8080/updateActivity";

    const putObject = {
        header: {'Content-type': 'application/json'
        },
        method: 'PUT',
        body: updateActivityStringified
    }

    console.log(putObject)

    fetch(putUrl, putObject)
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Create New Activity</title>
    <link rel="stylesheet" href="./static/styles.css">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
    <link rel="stylesheet" href="./static/bootstrap.min.css">
    <script type="text/javascript" th:src="@{/js/crud_activity.js}" defer></script>
</head>
<style>
    .center-screen
    {
        display: flex;
        flex-direction: column;
        justify-content: center;
        text-align: center;
        min-height: 25vh;
    }

    .update-activity
    {
        display: flex;
        flex-direction: column;
        justify-content: center;
        text-align: center;
        min-height: 25vh;
    }
</style>

<body>

<div class="center-screen">
    <h1>Ny aktivitet</h1>

    <form id="createForm" enctype="application/json" method="post"  action="/newActivity" onsubmit="submitForm()">
        <input id="title" type="text" placeholder="Titel" required/>
        <br>
        <input id="price" type="number" placeholder="Pris" step=".01" required/>
        <br>
        <input id="minHeight" type="number" max="250" placeholder="Højdekrav" required/>
        <br>
        <input id="minAge" type="number" max="110" placeholder="Alderskrav" required/>
        <br>
        <input id="equipment" type="text" placeholder="Udstyr" required/>
        <br>
        <input id="description" type="text" placeholder="Beskrivelse" required/>
        <br>
        <input id="imageLink" type="text" placeholder="Link" required/>
        <br>
        <input id="save" type="submit" value="Gem"/>
    </form>


<select id="dropdownAllActivities"></select>

<div class="update-activity">
    <h1>Update Activity</h1>
    <form id="update-activity" enctype="application/json" method="post" action="/updateActivity" onsubmit="updateSubmit()">
        <input id="title-update" type="text" placeholder="Titel" required/>
        <br>
        <input id="price-update" type="number" placeholder="Pris" step=".01" required/>
        <br>
        <input id="minHeight-update" type="number" max="250" placeholder="Højdekrav" required/>
        <br>
        <input id="minAge-update" type="number" max="110" placeholder="Alderskrav" required/>
        <br>
        <input id="equipment-update" type="text" placeholder="Udstyr" required/>
        <br>
        <input id="description-update" type="text" placeholder="Beskrivelse" required/>
        <br>
        <input id="imageLink-update" type="text" placeholder="Link" required/>
        <br>
        <input id="save-update" type="submit" value="Gem"/>
        <input id="delete" type="button" value="Slet"/>
    </form>
</div>
</div>

</body>
</html>

RestController:

package com.adventurealley.aafcro.restcontroller;

import com.adventurealley.aafcro.model.ActivityModel;
import com.adventurealley.aafcro.service.ActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@CrossOrigin(value = "*")
public class ActivityRestController {

    @Autowired
    private ActivityService activityService;

    @GetMapping("/findAllActivities")
    public List<ActivityModel> findAllActivities()
    {
        return activityService.getAllActivities();
    }

    @PostMapping(value = "/newActivity", consumes = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    public ActivityModel postActivity(@RequestBody ActivityModel activityModel)
    {
        return activityService.CreateActivity(activityModel);
    }

    @PutMapping(value = "/updateActivity", consumes = "application/json")
    public ActivityModel putActivity(@RequestBody ActivityModel updatedActivity) {
        return activityService.updateActivity(updatedActivity);
    }
}

Answer

In updateDB function header should be headers.

function updateDB(updateActivityStringified) {
    const putUrl = "http://localhost:8080/updateActivity";

    const putObject = {
        headers: {'Content-type': 'application/json'
        },
        method: 'PUT',
        body: updateActivityStringified
    }

    console.log(putObject)

    fetch(putUrl, putObject)
}

Leave a Reply

Your email address will not be published. Required fields are marked *