Getting a random axios 404
Answered
Montenegrin Mountain Hound posted this in #help-forum
Montenegrin Mountain HoundOP
Hi all,
I've got the following code:
I randomly get this error:
But then straight away the content loads after (its a valid page).
Any reason why?
I've got the following code:
'use client';
import Link from 'next/link';
import axios from 'axios';
import { Suspense } from 'react';
export default async function HandleIndex() {
return (
<div className='px-4 sm:px-6 lg:px-8'>
<div className='sm:flex sm:items-center'>
<div className='sm:flex-auto'>
<h1 className='text-base font-semibold leading-6 text-gray-900'>
Handles
</h1>
<p className='mt-2 text-sm text-gray-700'>
A list of all the handles you are currently tracking.
</p>
</div>
<div className='mt-4 sm:ml-16 sm:mt-0 sm:flex-none'>
<Link
href='/dashboard/handle/add'
type='button'
className='block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'
>
Add handle
</Link>
</div>
</div>
<Suspense fallback={<div>Loading...</div>}>
<HandleTable />
</Suspense>
</div>
);
}
async function HandleTable() {
const { data } = await axios.get('/api/handles');
return (
<div className='mt-8 flow-root'>
<div className='-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8'>
<div className='inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8'>
<div className='overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg'>
<table className='min-w-full divide-y divide-gray-300'>
<thead className='bg-gray-50'>
<tr>
<th
scope='col'
className='py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6'
>
Handle
</th>
<th
scope='col'
className='px-3 py-3.5 text-left text-sm font-semibold text-gray-900'
>
Status
</th>
<th scope='col' className='relative py-3.5 pl-3 pr-4 sm:pr-6'>
<span className='sr-only'>Edit</span>
</th>
</tr>
</thead>
<tbody className='divide-y divide-gray-200 bg-white'>
{data.map((handle) => (
<tr key={handle.username}>
<td className='whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6'>
{handle.username}
</td>
<td className='whitespace-nowrap px-3 py-4 text-sm text-gray-500'>
{handle.status}
</td>
<td className='relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6'>
<a
href='#'
className='text-indigo-600 hover:text-indigo-900'
>
Edit
<span className='sr-only'>, {handle.username}</span>
</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}I randomly get this error:
Unhandled Runtime Error
Error: Request failed with status code 404But then straight away the content loads after (its a valid page).
Any reason why?
Answered by Rafael Almeida
client components can't be async so they can't retrieve data like that, it needs to be done inside an
useEffect hook45 Replies
you shouldn't fetch your own API routes in server components, write the code of the endpoint directly in the component instead
Montenegrin Mountain HoundOP
I thought I marked it with use client though?
client components can't be async so they can't retrieve data like that, it needs to be done inside an
useEffect hookAnswer
Montenegrin Mountain HoundOP
ah really, thank you! What part would I need to change for this then?
British Shorthair
use
useState hookwhen the component is first rendered get the data
and update the state
remove the
async from the client components firstMontenegrin Mountain HoundOP
Ahh, thank you both!
Like this?
Like this?
'use client';
import Link from 'next/link';
import axios from 'axios';
import { Suspense, useEffect, useState } from 'react';
export default async function HandleIndex() {
return (
<div className='px-4 sm:px-6 lg:px-8'>
<div className='sm:flex sm:items-center'>
<div className='sm:flex-auto'>
<h1 className='text-base font-semibold leading-6 text-gray-900'>
Handles
</h1>
<p className='mt-2 text-sm text-gray-700'>
A list of all the handles you are currently tracking.
</p>
</div>
<div className='mt-4 sm:ml-16 sm:mt-0 sm:flex-none'>
<Link
href='/dashboard/handle/add'
type='button'
className='block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'
>
Add handle
</Link>
</div>
</div>
<HandleTable />
</div>
);
}
function HandleTable() {
const [handles, setHandles] = useState([]);
useEffect(() => {
axios.get('/api/handles').then((res) => {
setHandles(res.data);
});
});
if (!handles) {
return <div>Loading...</div>;
}
return (
<div className='mt-8 flow-root'>
<div className='-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8'>
<div className='inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8'>
<div className='overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg'>
<table className='min-w-full divide-y divide-gray-300'>
<thead className='bg-gray-50'>
<tr>
<th
scope='col'
className='py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6'
>
Handle
</th>
<th
scope='col'
className='px-3 py-3.5 text-left text-sm font-semibold text-gray-900'
>
Status
</th>
<th scope='col' className='relative py-3.5 pl-3 pr-4 sm:pr-6'>
<span className='sr-only'>Edit</span>
</th>
</tr>
</thead>
<tbody className='divide-y divide-gray-200 bg-white'>
{handles.map((handle) => (
<tr key={handle.username}>
<td className='whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6'>
{handle.username}
</td>
<td className='whitespace-nowrap px-3 py-4 text-sm text-gray-500'>
{handle.status}
</td>
<td className='relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6'>
<a
href='#'
className='text-indigo-600 hover:text-indigo-900'
>
Edit
<span className='sr-only'>, {handle.username}</span>
</a>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}British Shorthair
yes
if it works then yes
Montenegrin Mountain HoundOP
Perfect, weirdly if I spam refresh I get
British Shorthair
remove the
asyncfrom the first component
HandleIndexMontenegrin Mountain HoundOP
Ahhh thank you so much!! Quick and helpful support from both
British Shorthair
no problem
are you good by some chance in
nextauthMontenegrin Mountain HoundOP
I am still learning my way round next.js myself (from a laravel&vue background) but happy to try help
British Shorthair
so here is my stackoverflow post
no problem if you don't know what I did wrong
Montenegrin Mountain HoundOP
I'm using the vercel nextauth template, might be worth nabbing the code from that @British Shorthair https://vercel.com/templates/next.js/prisma-postgres-auth-starter
as it seems their authoptions are diff to yours
I don't think you need the
adapterBritish Shorthair
I'll look into that
thanks alot
yeah I know
I added it just in case that was crashing everything
Montenegrin Mountain HoundOP
And anytime, happy to try help in return by you both helping me. I'm using their starter template, just with some layout stuff and adding crud
British Shorthair
if you have any other questions dm me
Montenegrin Mountain HoundOP
Thank you a ton, I'm learning my way round haha gradually
Only thing I noticed, its constantly spamming requests
British Shorthair
because you only need to run
that function when the component is firstly rendered
just add an empty array
[] as a second parameter to the useEffectand you're good
useEffect(() => {
axios.get('/api/handles').then((res) => {
setHandles(res.data);
});
}, []);
axios.get('/api/handles').then((res) => {
setHandles(res.data);
});
}, []);
Montenegrin Mountain HoundOP
ahhh thank you, works! My laptop was getting hot and I couldn't figure why until I checked dev tools. what is that argument for? I'm confused why it would constantly call without
[]British Shorthair
because when you don't provide a second parameter the function runs everytime the component is rerendered
when state changes or an event happens (like a button is clicked)
Montenegrin Mountain HoundOP
Ahh because my method changes the state, thats why its re-triggered?
British Shorthair
well every event that happens
causes the component to re-trigger