- Published on
Resolving ECONNREFUSED Error in ShadCN DataTable with Axios in Next.js
- Authors
- Name
- Ripal & Zalak
When working with ShadCN UI DataTable in a Next.js application, you might encounter the following error while fetching data with Axios:
Error: connect ECONNREFUSED ::1:80
This error occurs when Axios cannot resolve the correct hostname for the API call. In this blog, we'll discuss the issue, its root cause, and how to resolve it effectively.
The Problem
You have a Next.js page component making a server-side call to an API using Axios:
async function getData(): Promise<Warga[]> {
const res = await axios.get('/api/data')
return res.data
}
However, this call results in the ECONNREFUSED
error because Axios defaults to http://localhost/api/data
, which is invalid in a server-side context.
Solution 1: Use the Full Hostname
To fix this issue, you need to provide the full hostname in the Axios request. This can be achieved by reading the host
header in your server component. Here's how:
import { headers } from 'next/headers'
import axios from 'axios'
async function getData(): Promise<Warga[]> {
const headersList = headers()
const host = headersList.get('host') // Get the host from headers
const res = await axios.get(`http://${host}/api/data`)
return res.data
}
This approach dynamically constructs the API URL based on the server's hostname.
Solution 2: Direct Database Query in Server Component
Since your DataPage
is a server component, you can eliminate the API route and fetch data directly from your Prisma database. This not only simplifies your architecture but also improves performance by reducing unnecessary HTTP calls.
getData
Function
Refactored import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function getData(): Promise<Warga[]> {
return await prisma.warga.findMany()
}
This approach bypasses the API route and directly queries the database.
Updated Page Component
import { DataTable } from './data-table'
import { columns } from './columns'
export default async function DataPage() {
const data = await getData()
return (
<div className="container mx-auto my-8 flex-col md:flex">
<div className="flex-1 space-y-4 pt-6 md:p-8">
<DataTable columns={columns} data={data} />
</div>
</div>
)
}
API Route Handler for Reference
If you want to retain the API route, here’s the corrected implementation:
import { NextResponse } from 'next/server'
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export const GET = async () => {
const wargaData = await prisma.warga.findMany()
return NextResponse.json(wargaData)
}
Key Takeaways
- Understand Server Context: Axios defaults to
http://localhost
for relative URLs, which can cause issues in server-side rendering. - Eliminate Unnecessary Routes: If possible, directly query the database in server components to simplify your architecture.
- Use Dynamic Hosts: When necessary, construct the full API URL using the
host
header.
FAQs
Q: Why use the full hostname in the API call?
A: Server-side Axios requests don’t automatically resolve relative URLs. Providing the full hostname ensures that the request is correctly routed.
Q: Is it better to fetch data directly from Prisma?
A: Yes, if the component is server-side, directly querying Prisma is faster and avoids unnecessary HTTP requests.
Q: What if I still encounter connection errors?
A: Check your Prisma client configuration and ensure that the database is running and accessible.