0

I am using NextJS and created three layers that separate the logic. The purpose is to minimise the error handling to the getServerSideProps section. I want to get all the lists from the database.

In the first layer, in the API route I created a folder called get-all-lists and a file [userId].js. The get request will be 'http://localhost:3000/api/get-all-lists/iudga937gr8'. Bellow there is the api route that get all the lists with the help of Prsima. It is working perfectly

import prisma from '../../../lib/prisma'



export default async function handler(req, res) {

    const { userId } = req.query;

    if (req.method === 'GET') {
      try {
        const shoppingLists = await prisma.List.findMany({ where: { userId: userId }});
        res.status(200).json({lists: shoppingLists});
      } 
      catch (error) {
        console.log(error);
        res.status(500).json({ message: 'Something went wrong. Please try again'});  
      }
    }
    else {
      res.status(500).json({message: 'Invalid method requested!'});
    }
}

The next layer, is the abstraction one which sent the final result to getServerSideProps. I created this because I need to fetch alot of requests and it would be too messy...

export const getAllLists = async userId => {
    try {
        const lists = await axios.get(`/api/get-all-lists/${userId}`);
        return lists;    
    } 
    catch (error) {
        console.log('Abstraction layer error: ', error);
        return 'Something went wrong. Please try again later';
    }
}

The problem arise here. In the postman I have the right result. In postman I use http://localhost:3000/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d and the server sent me the array specified.

But this function does not work and send me this error:

Abstraction layer error:  TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:371:5)
    at onParseError (node:internal/url:552:9)
    at new URL (node:internal/url:628:5)
    at dispatchHttpRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:176:20)
    at new Promise (<anonymous>)
    at http (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:112:10)
    at Axios.dispatchRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/dispatchRequest.js:51:10)
    at Axios.request (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:142:33)
    at Axios.<computed> [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:168:17)
    at Function.wrap [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/helpers/bind.js:5:15) {
  input: '/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d',
  code: 'ERR_INVALID_URL'
}

I also tried to paste the localhost in the browser and it have no problem.

juliomalves
  • 42,130
  • 20
  • 150
  • 146
daniel sas
  • 257
  • 2
  • 9
  • 1
    [You should not use `fetch()` to call an API route in `getServerSideProps`](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#getserversideprops-or-api-routes) – koolskateguy89 Dec 29 '22 at 22:05

1 Answers1

1

You could extract the functionality into /lib/getAllList.js:

import prisma from './prisma';

export default async function getAllLists(userId) {
  return await prisma.List.findMany({ where: { userId: userId }});
}

Then use it in your API route:

import getAllLists from '../../../lib/getAllLists';

export default async function handler(req, res) {
    const { userId } = req.query;

    if (req.method === 'GET') {
      try {
        const shoppingLists = await getAllLists(userId);
        res.status(200).json({lists: shoppingLists});
      } 
      catch (error) {
        console.log(error);
        res.status(500).json({ message: 'Something went wrong. Please try again'});  
      }
    }
    else {
      res.status(500).json({message: 'Invalid method requested!'});
    }
}

Then use it in getServerSideProps:

import getAllLists from 'path/to/lib/getAllLists';

export async function getServerSideProps(context) {
  const { userId } = context.params;
  const shoppingLists = await getAllLists(userId);

  return {
    props: {
      shoppingLists,
    },
  };
}
koolskateguy89
  • 276
  • 1
  • 9