'How to fetch data from endpoint in Sveltekit version v1.0.0-next.287
Yesterday I updated SvelteKit version from v1.0.0-next.241 to v1.0.0-next.287, and since I cannot fetch data in the component. I get an error message: Unexpected token < in JSON at position 0.
Error occurs when I try to parse response: await response.json()
Did anything change regarding fetching data since version 241? And how to do it now?
index.svelte
<script>
import { session } from '$app/stores';
import { onMount } from 'svelte';
onMount(async () => {
const response = await fetch('/content', {
method: 'POST',
body: JSON.stringify({
user_id: $session.user.id
}),
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json(); // error occurs on this line
});
</script>
index.js
export async function post({ request }) {
const data = await request.json();
try {
if (data.user_id > 0) {
let rows = await db.result;
if (rows.length > 0) {
return {
status: 200,
body: {
rows
},
headers: {
'Content-Type': 'application/json'
}
};
}
return {
status: 500,
body: {
rows: [],
message: 'endp result err: ' + rows.message
},
headers: {
'Content-Type': 'application/json'
}
};
}
return {
status: 400,
body: {
rows: [],
message: 'User not authorized'
},
headers: {
'Content-Type': 'application/json'
}
};
} catch (err) {
return {
status: 500,
body: {
rows: [],
message: 'endp other err: ' + err.message
},
headers: {
'Content-Type': 'application/json'
}
};
}
}
Postman result of requesting endpoint
<!DOCTYPE html>
<html lang="en" theme="white">
<head>
<meta charset="utf-8" />
<meta name="description" content="" />
<link rel="icon" href="../img/favicon.png" />
<link rel="stylesheet" href="../css/bootstrap-icons/bootstrap-icons.css" />
<link rel="stylesheet" href="../css/charts/styles.min.css" />
<link rel="stylesheet" href="../css/tiptap.css" />
<link rel="stylesheet" href="../css/all.css" />
<link rel="stylesheet" href="../css/global.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lighthouse - Login</title>
<style data-svelte>
.action-text.s-dYWHY7G7-e5q.s-dYWHY7G7-e5q {
font-size: 16px;
line-height: 20px;
text-decoration: none;
color: #fff;
width: 100%;
padding: 0 1rem
}
.action-text.s-dYWHY7G7-e5q>span.s-dYWHY7G7-e5q {
margin-left: 0.75rem;
vertical-align: top
}
.s-dYWHY7G7-e5q.s-dYWHY7G7-e5q {}
.action-link.s-u1xw7poppUIF {
text-align: center;
align-items: center;
vertical-align: middle;
justify-content: center;
padding-top: 10px
}
.s-u1xw7poppUIF {}
.search-wrapper.s-DzH6K7xlQw-L {
position: relative;
display: flex;
max-width: 28rem;
width: 100%;
margin-left: 0.5rem;
height: 3rem;
background-color: #393939;
color: #fff;
transition: max-width 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
.search-wrapper-hidden.s-DzH6K7xlQw-L {
max-width: 3rem;
background-color: #161616
}
.search-focus.s-DzH6K7xlQw-L {
outline: 2px solid #fff;
outline-offset: -2px
}
.search-wrapper-2.s-DzH6K7xlQw-L {
display: flex;
flex-grow: 1;
border-bottom: 1px solid #393939
}
.btn-search.s-DzH6K7xlQw-L {
width: 3rem;
height: 100%;
padding: 0;
flex-shrink: 0;
opacity: 1;
transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
.btn-search-disabled.s-DzH6K7xlQw-L {
border: none;
pointer-events: none
}
.input-search.s-DzH6K7xlQw-L {
font-size: 1rem;
font-weight: 400;
line-height: 1.375rem;
letter-spacing: 0;
color: #fff;
caret-color: #fff;
background-color: initial;
border: none;
outline: none;
width: 100%;
height: 3rem;
padding: 0;
transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
.input-hidden.s-DzH6K7xlQw-L {
opacity: 0;
pointer-events: none
}
.btn-clear.s-DzH6K7xlQw-L {
width: 3rem;
height: 100%;
padding: 0;
flex-shrink: 0;
opacity: 1;
display: block;
transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
.btn-clear.s-DzH6K7xlQw-L:hover {
background-color: #4c4c4c
}
.btn-clear-hidden.s-DzH6K7xlQw-L {
opacity: 0;
display: none
}
.s-DzH6K7xlQw-L {}
.subject-divider.s-CDH0hzNq6wMb.s-CDH0hzNq6wMb {
color: #525252;
padding-bottom: 4px;
border-bottom: 1px solid #525252;
margin: 32px 1rem 8px
}
.subject-divider.s-CDH0hzNq6wMb span.s-CDH0hzNq6wMb {
font-size: 0.75rem;
font-weight: 400;
line-height: 1rem;
letter-spacing: 0.32px;
color: #c6c6c6
}
.s-CDH0hzNq6wMb.s-CDH0hzNq6wMb {}
label.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
white-space: nowrap;
border: 0;
visibility: inherit;
clip: rect(0, 0, 0, 0)
}
[role="search"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
position: relative;
display: flex;
max-width: 28rem;
width: 100%;
margin-left: 0.5rem;
height: 3rem;
background-color: #393939;
color: #fff;
transition: max-width 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
[role="search"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn:not(.active) {
max-width: 3rem;
background-color: #161616
}
[role="search"].active.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
outline: 2px solid #fff;
outline-offset: -2px
}
[role="combobox"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
display: flex;
flex-grow: 1;
border-bottom: 1px solid #393939
}
input.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
width: 100%;
height: 3rem;
padding: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.375rem;
letter-spacing: 0;
color: #fff;
caret-color: #fff;
background-color: initial;
border: none;
outline: none;
transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
input.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn:not(.active) {
opacity: 0;
pointer-events: none
}
button.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
width: 3rem;
height: 100%;
padding: 0;
flex-shrink: 0;
opacity: 1;
transition: background-color 0.11s cubic-bezier(0.2, 0, 0.38, 0.9),
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9)
}
.disabled.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
border: none;
pointer-events: none
}
[aria-label="Clear search"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn:hover {
background-color: #4c4c4c
}
.hidden.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
opacity: 0;
display: none
}
ul.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
position: absolute;
z-index: 10000;
padding: 1rem 0;
left: 0;
right: 0;
top: 3rem;
background-color: #161616;
border: 1px solid #393939;
border-top: none;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.5)
}
[role="menuitem"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {
padding: 6px 1rem;
cursor: pointer;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.29;
letter-spacing: 0.16px;
transition: all 70ms cubic-bezier(0.2, 0, 0.38, 0.9);
display: block;
text-decoration: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #c6c6c6
}
.selected.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn,
[role="menuitem"].s-qIO5oRXzFdSn.s-qIO5oRXzFdSn:hover {
background-color: #353535;
color: #f4f4f4
}
[role="menuitem"].s-qIO5oRXzFdSn span.s-qIO5oRXzFdSn {
font-size: 0.75rem;
font-weight: 400;
line-height: 1.34;
letter-spacing: 0.32px;
text-transform: lowercase;
color: #c6c6c6
}
.s-qIO5oRXzFdSn.s-qIO5oRXzFdSn {}
</style>
</head>
<body>
<div id="svelte">
<div class="auth-bg">
<div class="auth-box p-4 m-auto">
<div>
<div><img src="/img/logo_orig.png" alt="logo" height="96"></div>
<div class="py-2">
<div class="bx--form-item bx--text-input-wrapper">
<label for="ccs-0.gurrqcw5ltk" class="false bx--label">
Username
</label>
<div class="bx--text-input__field-outer-wrapper">
<div class="bx--text-input__field-wrapper">
<input id="ccs-0.gurrqcw5ltk" placeholder="Enter username..." type="email" value="" class="bx--text-input ">
</div>
</div>
</div>
</div>
<div class="py-2">
<div class="bx--form-item bx--text-input-wrapper">
<label for="ccs-0.xn3g2icn4s7" class="false bx--label">
Password
</label>
<div class="bx--text-input__field-outer-wrapper">
<div class="bx--text-input__field-wrapper">
<input id="ccs-0.xn3g2icn4s7" placeholder="Enter password..." type="password" value="" class="bx--text-input ">
</div>
</div>
</div>
</div>
<div class="py-4">
<button type="button" tabindex="0" class="bx--btn bx--btn--primary">
Log in</button></div>
<div class="py-2">or
<a href="/auth/register" class="bx--link ">Register</a></div>
<div class="py-2">
<a href="/auth/restore" class="bx--link ">Forgot password?</a></div>
</div>
</div>
<div class="company-logo"><a href="https://www.fh-swf.de/en/"
target="_blank"><img src="/img/company-logo.png" alt="company-logo" height="64"></a>
</div>
</div>
<div class="bx--loading-overlay ">
<div aria-atomic="true" aria-labelledby="ccs-0.lnde8bksux9" aria-live="assertive"
class="bx--loading">
<label id="ccs-0.lnde8bksux9" class="bx--visually-hidden">Active loading indicator</label>
<svg viewBox="0 0 100 100" class="bx--loading__svg">
<title>Active loading indicator</title>
<circle cx="50%" cy="50%" r="44" class="bx--loading__stroke"></circle>
</svg></div>
</div>
<script type="module" data-hydrate="1xenv5n">
import { start } from "/@fs/Users/elshad/OneDrive/Projects/FH-SWF/StudentAssistant/LighthouseApp/.svelte-kit/runtime/client/start.js";
start({
target: document.querySelector('[data-hydrate="1xenv5n"]').parentNode,
paths: {"base":"","assets":""},
session: {authenticated:false},
route: true,
spa: false,
trailing_slash: "never",
hydrate: {
status: 200,
error: null,
nodes: [
import("/src/routes/auth/__layout.reset.svelte"),
import("/src/routes/auth/login/index.svelte")
],
params: {}
}
});
</script>
<script type="application/json" data-type="svelte-props">
{}
</script>
</div>
</body>
</html>
Solution 1:[1]
You have to add accept
headers as well to indicate to the server what you accept as a return, by default this is html.
headers: {
"content-type": "application/json",
"accept": "application/json"
}
Solution 2:[2]
Could be related to this? I stumbled upon it when researching how to Post files to the filestore.
Breaking: use Request and Response objects in endpoints and hooks #3384
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Stephane Vanraes |
Solution 2 | npasco |