#Cant display data from api on my nextjs 14 app router project

1 messages · Page 1 of 1 (latest)

cursive knotBOT
#

Hi @brave granite. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

I'm sorry, but I don't have enough information to provide a solution to your problem. Could you please provide more details about the issue you're facing? For example, it would be helpful to know how you're fetching the data from the API, how you're trying to display it, and any error messages you're seeing.

In the meantime, you might find it helpful to review the Next.js documentation on data fetching (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) and routing (https://nextjs.org/docs/app/building-your-application/routing).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@brave granite kapa.ai is still learning and improving, please let us know how it did by reacting below

brave granite
#

here is how im fetching the data from api @cursive knot import React from 'react';
import { getJobDetails } from '@/app/api/jsearch/route';
import { JobDetailsResponse } from '../../../../types/job';

interface JobDetailsPageProps {
params: {
jobId: string;
};
}

const fetchJobDetails = async (jobId: string) => {
try {
console.log('Fetching job details for Job ID:', jobId); // Debugging statement
const response: JobDetailsResponse = await getJobDetails(jobId, {
extended_publisher_details: 'true',
});
console.log('API Response:', response); // Debugging statement
return response;
} catch (error) {
console.error('Error fetching job details:', error);
return null;
}
};

export default async function JobDetailsPage({ params: { jobId } }: JobDetailsPageProps) {
jobId = decodeURIComponent(jobId); // Decode jobId if it's URL encoded
console.log('Decoded Job ID:', jobId); // Debugging statement
const jobPreview = await fetchJobDetails(jobId);

console.log('Job Preview:', jobPreview); // Debugging statement

if (!jobPreview) {
return <div>No job details found.</div>;
}

return (
<div>
<h1>{jobPreview.job_title}</h1>
<h1>Job ID: {jobPreview.job_id}</h1>
<p>Employer: {jobPreview.employer_name}</p>
{jobPreview.employer_logo && (
// eslint-disable-next-line @next/next/no-img-element
<img src={jobPreview.employer_logo} alt={${jobPreview.employer_name} Logo} style={{ width: '100px', height: '100px' }} />
)}
<p>Website: {jobPreview.employer_website ? <a href={jobPreview.employer_website}>{jobPreview.employer_website}</a> : 'No website available'}</p>
<p>{jobPreview.job_description}</p>
</div>
);
}

cursive knotBOT
#

Let me check the knowledge base for you. One moment! :books:

#

From the code you've provided, it seems like you're trying to fetch job details from an API and display them on a page. However, it's important to note that in Next.js, data fetching for pages should be done using specific functions like getStaticProps, getServerSideProps, or getInitialProps.

In your case, you're fetching the data inside the component itself, which might not work as expected, especially if the data fetching is asynchronous.

Here's a simplified example of how you might use getServerSideProps to fetch data for your page:

export async function getServerSideProps(context) {
  const jobId = context.params.jobId;
  const jobDetails = await fetchJobDetails(jobId);

  return {
    props: {
      jobDetails,
    },
  };
}

export default function JobDetailsPage({ jobDetails }) {
  if (!jobDetails) {
    return <div>No job details found.</div>;
  }

  return (
    <div>
      <h1>{jobDetails.job_title}</h1>
      <h1>Job ID: {jobDetails.job_id}</h1>
      <p>Employer: {jobDetails.employer_name}</p>
      {jobDetails.employer_logo && (
        // eslint-disable-next-line @next/next/no-img-element
        <img src={jobDetails.employer_logo} alt={`${jobDetails.employer_name} Logo`} style={{ width: '100px', height: '100px' }} />
      )}
      <p>Website: {jobDetails.employer_website ? <a href={jobDetails.employer_website}>{jobDetails.employer_website}</a> : 'No website available'}</p>
      <p>{jobDetails.job_description}</p>
    </div>
  );
}

In this example, getServerSideProps fetches the data before the page is rendered, and the fetched data is passed to the page component as a prop.

Please note that getServerSideProps runs on every request, so it's best used for data that changes frequently. If your data can be statically generated at build time, consider using getStaticProps instead.

#

@brave granite kapa.ai is still learning and improving, please let us know how it did by reacting below

brave granite
#

no @cursive knot im using App router on my project

cursive knotBOT
#

Let me check the knowledge base for you. One moment! :books:

#

I see, you're using the App Router in your Next.js project. In this case, you should be using Server Components to fetch and render data.

Server Components in Next.js allow you to create components that are rendered on the server and sent to the client as HTML. This means you can fetch data and render it on the server, without having to worry about client-side data fetching.

Here's a simplified example of how you might use a Server Component to fetch and display your job details:

import {getJobDetails} from '@/app/api/jsearch/route';
import {JobDetailsResponse} from '../../../../types/job';

async function JobDetails({jobId}) {
  jobId = decodeURIComponent(jobId); // Decode jobId if it's URL encoded
  const jobDetails = await getJobDetails(jobId);

  if (!jobDetails) {
    return <div>No job details found.</div>;
  }

  return (
    <div>
      <h1>{jobDetails.job_title}</h1>
      <h1>Job ID: {jobDetails.job_id}</h1>
      <p>Employer: {jobDetails.employer_name}</p>
      {jobDetails.employer_logo && (
        // eslint-disable-next-line @next/next/no-img-element
        <img src={jobDetails.employer_logo} alt={`${jobDetails.employer_name} Logo`} style={{ width: '100px', height: '100px' }} />
      )}
      <p>Website: {jobDetails.employer_website ? <a href={jobDetails.employer_website}>{jobDetails.employer_website}</a> : 'No website available'}</p>
      <p>{jobDetails.job_description}</p>
    </div>
  );
}

export default JobDetails;

In this example, JobDetails is a Server Component that fetches job details based on the jobId prop and renders them. Note that Server Components must be named with a .server.js extension, and they can only be imported into other Server Components or into _app.server.js.

#

@brave granite kapa.ai is still learning and improving, please let us know how it did by reacting below

brave granite
#

its also in type script keep that in mind @cursive knot

cursive knotBOT
#

Let me check the knowledge base for you. One moment! :books:

#

I see, you're using TypeScript in your project. In that case, you would need to add types to your Server Component. Here's how you might modify the previous example to use TypeScript:

import { getJobDetails } from '@/app/api/jsearch/route';
import { JobDetailsResponse } from '../../../../types/job';

interface JobDetailsProps {
  jobId: string;
}

const JobDetails: React.FC<JobDetailsProps> = async ({ jobId }) => {
  jobId = decodeURIComponent(jobId); // Decode jobId if it's URL encoded
  const jobDetails: JobDetailsResponse = await getJobDetails(jobId);

  if (!jobDetails) {
    return <div>No job details found.</div>;
  }

  return (
    <div>
      <h1>{jobDetails.job_title}</h1>
      <h1>Job ID: {jobDetails.job_id}</h1>
      <p>Employer: {jobDetails.employer_name}</p>
      {jobDetails.employer_logo && (
        // eslint-disable-next-line @next/next/no-img-element
        <img src={jobDetails.employer_logo} alt={`${jobDetails.employer_name} Logo`} style={{ width: '100px', height: '100px' }} />
      )}
      <p>Website: {jobDetails.employer_website ? <a href={jobDetails.employer_website}>{jobDetails.employer_website}</a> : 'No website available'}</p>
      <p>{jobDetails.job_description}</p>
    </div>
  );
};

export default JobDetails;

In this example, JobDetails is a Server Component that fetches job details based on the jobId prop and renders them. Note that Server Components must be named with a .server.tsx extension, and they can only be imported into other Server Components or into _app.server.tsx.