Two errors for Nextjs: res.json is not a function and getserversideprops did not return an object

Viewed 2438

I'm trying to make an api request and I do get the data because I tried console logging it and it shows on the console but I still get errors. Here are the errors:

TypeError: res.json is not a function

Error: Your `getServerSideProps` function did not return an object. Did you forget to add a `return`?
    

Here is my code:

export async function getServerSideProps(context) {
  // API KEYS
  const apiKeyLocationIQ = process.env.API_KEY_LOCATIONIQ;
  const apiKeyWeather = process.env.API_KEY_WEATHER;
  // API REQUEST OPTIONS
  let cityLocationIQ = context.params.location;
  let urlLocationIQ = "https://api.locationiq.com/v1/search.php?format=JSON&key="+apiKeyLocationIQ+"&q="+cityLocationIQ+"&limit=1";
  // API REQUEST FOR LAT AND LON
  try{
    const res = await axios.get(urlLocationIQ).then((resLocation)=>{
      return resLocation
    })
    const weather = await res.json();
    return {
      props: {
        weather
      }
    }
  }catch (error){
    console.log( error);
  }
  
}

UPDATE I made some changes to the axios request and I get a different error. This time it says:

function cannot be serialized as JSON. Please only return JSON serializable data types.

here is how my updated axios request looks like:

try{
    const res = await axios.get(urlLocationIQ, {responseType: 'json'})
    const weather = await res;
    return {
      props: {
        weather
      }
    }
  }catch (error){
    console.log( error);
    throw error;
  }

FINAL UPDATE So it turns out that the axios request that I sent returns the entire request data including the headers etc. and the data that I needed was an object at the very bottom of the response, so all I had to do was to specify the data I needed. Here is my code:

const location = await axios.get(urlLocationIQ).then((resLocation)=>{
      return {resLocation.data[0]}
    })

After that, the code works perfectly now.

1 Answers

To my knowledge, the value that axios.get() resolves to does not have a .json() method so thus the error you get.

You can tell Axios, ahead of time that you want it to parse a JSON response for you automatically.

const weather = (await axios.get(urlLocationIQ, {responseType: 'json'})).data;

But, that responseType is the default, so you can actually just do this assuming your response actually returns JSON:

const weather = (await axios.get(urlLocationIQ)).data;

I would assume you were perhaps expecting a .json() method like the fetch() interface uses, but that is not required with axios. By default axios reads the response body for you whereas the fetch() interface does not read the response body (other than the headers) until you specifically call a method such as .json(). But, that's not how axios works. In this regard, axios often requires less lines of code to make a request and get the response.


P.S. Note that the .then() here:

.then((resLocation)=>{
  return resLocation
})

is pointless. The promise already resolves to that value so adding a .then() that just returns it again is of no use.


Also, note that getServerSideProps() is an async function. That means that it ALWAYS returns a promise and the resolved value of that promise will be whatever value you return from inside your function. The caller of that function needs to either use await or .then() to get the resolved value.


And, in your catch(), you need to rethrow the error so that the caller gets the error. Otherwise, you will just be eating the error and resolving the promise with undefined since there will be no return value.

} catch (error) {
    console.log( error);
    throw error;
}
Related