What could be the reason for the Nextjs fetch request returning undefined data?

Here is the code snippet for my GET request in the API section:

export default async (req, res) => {
  const { query: { className }, method } = req;

  switch (method) {
    case "GET":
      try {
        const classDetail = await Class.findOne({title: className});
        if (!classDetail) {
          return res.status(400).json({ success: false });
        }
        res.status(200).json({ success: true, data: classDetail });
      } catch (error) {
        res.status(400).json({ success: false });
        console.log(error);
      }
      break;
    default:
      res.status(400).json({ success: false });
  }

On my [className] page, I am attempting to retrieve data from the following API endpoint:

http://localhost:3000/api/admin/classes/${className}
. However, when I log the response, it shows as undefined.

export async function getServerSideProps({ query: { className } }) {
  const res = await fetch(`http://localhost:3000/api/admin/classes/${className}`)
    .then(() => console.log(`first get request sent: `));

  // const { data } = await res.json();
  console.log(res)

  return { props: { classDetail: 1 } };
}

Interestingly, when I make the same GET request using Postman with the endpoint

http://localhost:3000/api/admin/classes/class-3
, it returns the expected data. Why am I not receiving the same data within getServerSideProps?

{
    "success": true,
    "data": {
        "_id": "62f6858ea26fbb47b3cc0563",
        "title": "class-3",
        "classImageURL": "http://res.cloudinary.com/nhnasem/image/upload/v1660323222/HELP_ME_ewcr5t.png",
        "imageWidth": "1555",
        "imageHeight": "2000",
        "__v": 0
    }
}

What could be causing this issue and how can I resolve it?

Edit: I also tested it with the JSONPlaceholder API, but encountered the same 'undefined' result.

Edit 2: Handling requests for two APIs

export async function getServerSideProps({ query: { className } }) {
  const res = await fetch(
    `http://localhost:3000/api/admin/classes/${className}`
  );

  const {data} = res.json()

  const res2 = await fetch(
    `http://localhost:3000/api/admin/classes/${className}/subjects`
  );

  const {data} = await res2.json()   // this won't work as it was already called and declared before
  return { props: { classDetail: data, subjects: data} }; 
}

Answer №1

The issue arises from the additional .then() you have included in your fetch call.

When you append a .then() to a promise chain, it takes the result of the initial fetch as its argument and is expected to return the desired result of a promise. In this scenario, you are not returning anything, leading to the presence of undefined in your res variable. Instead, it is recommended to return the original outcome:

const res = await fetch(`http://localhost:3000/api/admin/classes/${className}`)
    .then((res) => { console.log(`first get request sent: `); return res; });

or alternatively eliminate

.then(() => console.log(`first get request sent: `));

UPDATE If both responses contain an object with a data property, you cannot destructure both outcomes using the same variable name:

const {data} = await res.json()
const {data} = await res2.json();

In such cases, specify the variable that should hold the data:

const {data: classDetail} = await res.json()
const {data: subjects} = await res2.json();

return { props: { classDetail, subjects} };

or provide more clarity:

const json = await res.json()
const json2 = await res2.json();

return { props: { classDetail: json.data, subjects: json2.data} };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to remove items from Vuex store by utilizing a dynamic path as payload for a mutation

I am looking to implement a mutation in Vuex that dynamically updates the state by specifying a path to the object from which I want to remove an element, along with the key of the element. Triggering the action deleteOption(path, key) { this.$store.d ...

Are you looking to refresh the Amplify Redirect URL?

Is there a way to update the redirection URI for Amplify signout in the 'aws-exports' file? What steps should be taken to make this change? Can we simply modify the file directly and then execute 'amplify push'? Update After attempti ...

Looking to display all items once the page has finished loading

I am experiencing a minor issue. Every time I access my store page where all products are listed, I have to click on the size filter to load the products. This is not ideal as I want all products to be displayed automatically when the page loads. What modi ...

Issue encountered while attempting to run Next.js application. Halts abruptly shortly after initialization

After installing the Next.js app, I encountered an issue where the app would not start and would stop immediately. My terminal displayed the following: PS D:\Nextjs\MyApp> npm run dev > dev > next dev ready - started server on 0.0.0.0: ...

An issue arises when attempting to utilize v-model with a file input

Is there a way to reset a file input field in Vue.js after uploading a file? I attempted to set the v-model value to null, but encountered an error message that said: File inputs are read only. Use a v-on:change listener instead. This is my current cod ...

What is the process for importing a sprite sheet along with its JSON file into my Phaser game?

Currently, I am in the process of developing a game using the powerful phaser game engine. To enhance the visual appeal of my game, I decided to create a sprite sheet and successfully downloaded it. The sprite sheet consists of a 256 × 384 .png file ...

Embed a Vaadin component within an element dynamically generated by a Javascript component

I am currently designing a Vaadin application and working on a custom Javascript component, which is a subclass of AbstractJavascriptComponent. This component uses jQuery to generate a table-like structure. In certain scenarios, users should be able to in ...

How to convert typescript path aliases into relative paths for NPM deployment?

I am currently working on a typescript project that utilizes paths for imports. For instance: "paths": { "@example/*": ["./src/*"], } This allows the project to import files directly using statements like: import { foo } from "@example/boo/foo"; Whe ...

What is the best way to reset local state after triggering a success action in Redux Saga?

I'm looking to reset my component state after a successful call in redux saga. Is there a way to achieve this? Currently, I am using the component state to track my input value. this.state = { department: '', }; The solution I have im ...

Develop a Vue mixin to enable theme switching in a Vue.js application

I have successfully developed three distinct themes: light, default, and dark. Currently, I am working on implementing a toggle function in the footer section that allows users to switch between these themes effortlessly. Following the guidance provided b ...

Foreign keys in a one-to-many relationship with Sequelize.js

I am in the process of developing a survey application using Node.js/Express and MySQL incorporating Sequelize.js ORM. However, I am encountering difficulties while establishing the relationship between the two models. My goal is to have the Questions&apo ...

Node.Js made user authentication effortless

Struggling to integrate user authentication using Passport, Express, and Node.Js as tutorials mostly focus on MongoDB. However, I prefer Neo4J for my database. The examples on passport-local don't fit my needs since I've already implemented a loc ...

Managing read replication delay while using nextjs revalidatePath: Tips and tricks

Consider a scenario where a nextJS application is writing to a database in a server action, updating a counter, and then calling revalidate. However, due to replication lag from reading data on a replica, the revalidatePath does not work immediately. Only ...

The Angular Material dialog fails to display content when triggered within an event listener in Google Maps

Within my project, I am utilizing Angular 6.0.6 and Angular Material 6.3.0. One issue I have encountered is with a dialog component that I have added to the entryComponents in the app module. Strangely, when I attempt to open this dialog within the rightcl ...

Show the information obtained from the dropdown menu selection

Upon selecting a different item from the drop-down list, I want the specific data related to that field from the MySQL database to be displayed. Currently, I am able to retrieve the value of the selected item in the dropdown menu but encountering difficul ...

Use jQuery to set the onclick attribute for all elements rather than relying on inline JavaScript

I am currently facing a challenge with converting inline JS to jQuery. My goal is to eliminate all inline onclick events and instead target them by class. HTML - checkbox <td class="center"> <?php if ($product['selected']) { ?> ...

Ensuring the accurate promise is delivered in Angular

I'm struggling to correctly return the promise for a service in Angular. Here is the function causing me trouble: postToSP.post($scope.sharePointURL, data).then(function() { $scope.gettingData = false; $scope.yammerListName = ...

Learn how to execute shell commands on a Linux server from a Node.js application by utilizing Socket.io for establishing a connection. This includes tasks such as running "ls -ltr", changing

After successfully establishing a connection with my Linux server, I aim to execute shell commands for automation purposes such as changing directories and creating new folders. The main objective is to connect to the Linux server through a webpage, wher ...

Managing time-intensive web service operations using JavaScript callbacks

One of the operations in my Web application involves a function that returns a value, which then needs to be passed to a web service method running separately from the application. This web service operation takes some time to complete and therefore must r ...

Clear existing markers from the map before inserting new markers

I have a map where initially the markers load coming from the database, Then there is a time-based Ajax request that fetches new records every minute. In my code snippet, I am using setMapOnAll(null) following the guidance from the Google Maps Documentati ...