Server components with server side calls on "next": "^13.5.3" keeps bringing cached/old api response
Unanswered
Fire ant posted this in #help-forum
Fire antOP
I am using "next": "^13.5.3" and making a server pulling using server functions. As using option "reload" on nextJS v13.5.3, it seems that the result from this api call is being cached. While an insomnia response returns status: "scan-finished", the getProjectData() returns 'pending'. If i reload the page or go back and open the project page again, the data from project is correctly returned, but the old api call keeps opened and being called each 10 seconds, returning status: 'pending"
Code Below:
Code Below:
13 Replies
Fire antOP
async function onProcessAnalysisResults(projectId: string) {
const jwt = cookies().get(COOKIES_KEYS.USER_JWT)
const userId = cookies().get(COOKIES_KEYS.USER_ID)
const fuzzingGroupId = cookies().get(COOKIES_KEYS.FUZZING_GROUP_ID)
await fetch(`https://baseURLHidden/v1/analyze/process`, {
body: JSON.stringify({
userId: userId?.value,
fuzzingGroupId: fuzzingGroupId?.value,
}),
method: 'POST',
cache: 'reload',
headers: {
Authorization: `Bearer ${jwt?.value}`,
'Content-Type': 'application/json',
},
}).then(async (res) => {
if (res.status === 500) {
await new Promise(() => {
setTimeout(() => {
console.log('IS CALLING AGAIN')
onProcessAnalysisResults(projectId)
}, 1000 * 30) // 3O seconds
})
} else {
console.log('res.status', res.status)
await new Promise(() => {
setTimeout(() => {
getProjectData(projectId)
}, 10000) // 10 seconds
})
}
})
}
async function getProjectData(projectId: string) {
const jwt = cookies().get(COOKIES_KEYS.USER_JWT)
console.log('jwt', jwt)
const response = await fetch(
`https://baseURLHidden/v1/projects/${projectId}/vulnerabilities`,
{
cache: 'reload',
headers: {
Authorization: `Bearer ${jwt?.value}`,
'Cache-Control': 'no-store',
},
},
)
console.log('response', response)
const projectDetails = await response.json()
console.log('projectDetails', projectDetails)
console.log('projectDetails.status', projectDetails.status)
if (projectDetails.status === 'pending') {
console.log('IS PENDING YET')
await onProcessAnalysisResults(projectId)
} else {
console.log('IS NOT PENDING')
return projectDetails
}
}Fire antOP
Example of server console.log()
projectDetails {
_id: '651d8d991def331b91d54934',
userId: '651c154852e3038d194d3d38',
fuzzingGroupId: '651d8d9957370d001a728ac8',
status: 'pending',
numberUnknownVulns: 0,
numberLowVulns: 0,
numberMediumVulns: 0,
numberHighVulns: 0,
githubRepo: 'https://github.com/PatrickAlphaC/hardhat-erc20-fcc',
gptInsight: 'Waiting analysis results.',
vulnerabilities: [],
analyses: [
{
solidityFile: '/contracts/ManualToken.sol',
uuid: 'e518908f-1064-42f9-a910-21a040ee539d',
_id: '651d8d9c1def331b91d54947',
detectedIssues: []
},
{
solidityFile: '/contracts/OurToken.sol',
uuid: '4c7c9ec6-fe9e-4702-bc8b-5c9e08cfb6e9',
_id: '651d8d9c1def331b91d54948',
detectedIssues: []
}
],
__v: 1
}
projectDetails.status pending
IS PENDING YET
IS CALLING AGAIN
IS CALLING AGAIN
IS CALLING AGAIN
IS CALLING AGAIN
IS CALLING AGAIN
res.status 200
projectDetails {
_id: '651d8d991def331b91d54934',
userId: '651c154852e3038d194d3d38',
fuzzingGroupId: '651d8d9957370d001a728ac8',
status: 'pending',
numberUnknownVulns: 0,
numberLowVulns: 0,
numberMediumVulns: 0,
numberHighVulns: 0,
githubRepo: 'https://github.com/PatrickAlphaC/hardhat-erc20-fcc',
gptInsight: 'Waiting analysis results.',
vulnerabilities: [],
analyses: [
{
solidityFile: '/contracts/ManualToken.sol',
uuid: 'e518908f-1064-42f9-a910-21a040ee539d',
_id: '651d8d9c1def331b91d54947',
detectedIssues: []
},
{
solidityFile: '/contracts/OurToken.sol',
uuid: '4c7c9ec6-fe9e-4702-bc8b-5c9e08cfb6e9',
_id: '651d8d9c1def331b91d54948',
detectedIssues: []
}
],
__v: 1
}
projectDetails.status pending
IS PENDING YETAfter page refresh ==>
And then it keeps infinitely returning the pending status and calling the api again
as with the data being correctly loaded
Plott Hound
when you build the project how are the pages being rendered? SSR or static?
could try this: export const revalidate = 0;
could try this: export const revalidate = 0;
Fire antOP
My build output:
✓ Generating static pages (15/15)
✓ Collecting build traces
✓ Finalizing page optimization
Route (app) Size First Load JS
┌ ○ / 255 kB 393 kB
├ ○ /_not-found 880 B 84.7 kB
├ ○ /account/billing 3.07 kB 102 kB
├ ○ /account/connected-accounts 3.17 kB 96.7 kB
├ ○ /account/overview 4.83 kB 198 kB
├ λ /api/reload-data 0 B 0 B
├ ○ /audit 18.2 kB 199 kB
├ λ /audit/[contractAddress]/result 41.1 kB 177 kB
├ ○ /forget-password 5.23 kB 186 kB
├ ○ /payment-refused 2.67 kB 131 kB
├ ○ /payment-successful 2.57 kB 131 kB
├ λ /projects 10.6 kB 150 kB
├ λ /projects/[projectId] 9.75 kB 166 kB
├ λ /projects/[projectId]/files/[file] 4.17 kB 113 kB
├ λ /reset/[resetToken] 3.54 kB 185 kB
├ ○ /sign-in 5.95 kB 194 kB
â”” â—‹ /sign-up 3.69 kB 192 kB
+ First Load JS shared by all 83.9 kB
├ chunks/26-f4deffe9cb6e9dc0.js 28.1 kB
├ chunks/bf6a786c-d6dbf367fca56d80.js 53.7 kB
├ chunks/main-app-0273fe392a6bac14.js 232 B
â”” chunks/webpack-f81f762555cdaa24.js 1.85 kB
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
â—‹ (Static) automatically rendered as static HTML (uses no initial props)Where exactly should I place this?
is this automatically understood by Next the same way export const metadata = ... is?
export const revalidate = 0;is this automatically understood by Next the same way export const metadata = ... is?
Fire antOP
I tried doing this
but keeps not working
export const revalidate = 0;but keeps not working
Fire antOP
I fixed it by creating an endpoint inside app/api that fetches the same endpoint from my backend. It retrieves now the correct date, however I believe it's not the best workaround. Althought, now the loading.tsx does not stop being triggered, as after my api calls end and I return the data, the loading keeps showing on my screen:
My code:
My code:
async function onProcessAnalysisResults(projectId: string) {
const jwt = cookies().get(COOKIES_KEYS.USER_JWT)
const userId = cookies().get(COOKIES_KEYS.USER_ID)
const fuzzingGroupId = cookies().get(COOKIES_KEYS.FUZZING_GROUP_ID)
await fetch(`https://api.bytecode.ai/v1/analyze/process`, {
body: JSON.stringify({
userId: userId?.value,
fuzzingGroupId: fuzzingGroupId?.value,
}),
method: 'POST',
cache: 'reload',
headers: {
Authorization: `Bearer ${jwt?.value}`,
'Content-Type': 'application/json',
},
}).then(async (res) => {
if (res.status === 500) {
await new Promise(() => {
setTimeout(() => {
console.log('IS CALLING AGAIN')
onProcessAnalysisResults(projectId)
}, 1000 * 30) // 3O seconds
})
} else {
console.log('res.status', res.status)
return reloadData(projectId)
}
})
}
async function getProjectData(projectId: string) {
const jwt = cookies().get(COOKIES_KEYS.USER_JWT)
const response = await fetch(
`https://api.bytecode.ai/v1/projects/${projectId}/vulnerabilities`,
{
cache: 'reload',
headers: {
Authorization: `Bearer ${jwt?.value}`,
'Cache-Control': 'no-store',
},
},
)
const projectDetails = await response.json()
if (projectDetails.status === 'pending') {
return onProcessAnalysisResults(projectId)
} else {
return projectDetails
}
}reloadData funct:
export const revalidate = 0
async function reloadData(projectId: string) {
const jwt = cookies().get(COOKIES_KEYS.USER_JWT)
const host = headers().get('host')
const protocal = process?.env.NODE_ENV === 'development' ? 'http' : 'https'
const response = await fetch(`${protocal}://${host}/api/reload-data`, {
method: 'POST',
body: JSON.stringify({
projectId,
}),
headers: {
Authorization: `Bearer ${jwt?.value}`,
'Content-Type': 'application/json',
},
})
const data = await response.json()
console.log('Reload data', data.projectDetails)
return data.projectDetails
}Page return:
export default async function ProjectPage({
params,
}: {
params: { projectId: string }
}) {
const project: ProjectDataProps = await getProjectData(params.projectId)
return...
}If I just call this way:
the page loads fine
const project: ProjectDataProps = await reloadData('651d6b62ff7600818f81ac82')the page loads fine