英文:
TypeError: Cannot read properties of undefined when making AirTable API call with NextJS 13.4
问题
我正在学习使用 NextJS 13.4 的新 App 路由器,但在尝试进行外部 API 调用时遇到了错误。
实际上,我从 Airtable 正确地接收到了所有数据,但由于 Next 抛出了这个错误,它导致了我的 try-catch 出现问题。我无法弄清楚是什么导致了这个错误,以及如何修复它。
以下是它抛出的错误信息:
- 错误 TypeError: 无法读取未定义的属性(读取 'headers')
    在 eval(webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:254:61)
    在 processTicksAndRejections(node:internal/process/task_queues:96:5)
我是从位于 /app/dashboard/page.js 的客户端组件中进行初始调用的。
page.js 大致如下:
'use client'
import React, { useEffect } from 'react';
const Dashboard = () => {
  useEffect(() => {
    async function fetchData() {
      try {
        const res = await fetch('/api/jobs', {
          method: 'GET',
          headers: {
            'id': '123'
          }
        });
        const data = await res.json();
        console.log("hello", data); // 我从未达到这个控制台日志,因为下面的 catch 捕捉了错误
      } catch (error) {
        console.log("error")
        console.log(error);
      }
    };
    fetchData();
  }, []);
  
  return (
    <div>
      你好,世界
    </div>
  );
}
export default Dashboard;
然后,我在 /app/api/jobs/route.js 中有我的处理程序。
route.js 大致如下:
import { NextResponse } from 'next/server';
import { jobs } from "../../../utils/Airtable";
 
export async function GET(req) {
  let headers = await req.headers.get('id'); // 这很好地记录了标头
  let recordsArr = [];
  try {
        jobs.select({
            view: 'Grid view',
            fields: ['Project Lead'],
            filterByFormula: `AND({Project Lead} = 'Jane Doe', AND({Created Day}, '6/1/23'))`
        }).eachPage(function page(records, fetchNextPage) {
                recordsArr.push(...records);
                
                try {
                    fetchNextPage();
                } catch (err) {
                    console.log(err)
                    return;
                };
            }, function done(err) { 
                if (err) {
                    return new NextResponse(JSON.stringify({message: 'Error'})) 
                };
                console.log(recordsArr) // 这完美地记录了记录
                return new NextResponse(JSON.stringify(recordsArr));
        });
    } catch (err) {
        return new NextResponse(JSON.stringify({message: 'Error'}), { status: 500 })
    };
  return new NextResponse(JSON.stringify(obj), { status: 200 });
}
一旦我注释掉 Airtable API 调用,就不再收到错误。
如果我将整个 Airtable API 调用移到客户端组件中,它就可以无缝运行。所以我认为有关 NextJS 我还没有理解的一些事情。
感谢您的时间。
英文:
I'm learning the new App router using NextJS 13.4 and have come across an error when attempting to make an external api call.
I actually receive all of the data properly from Airtable but because Next throws this error it causes my try catch to break. I cannot for the life of me figure out what is throwing this error and how to fix it.
Here is the error it is throwing:
- error TypeError: Cannot read properties of undefined (reading 'headers')
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:254:61)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
I am making the initial call from a client component located at /app/dashboard/page.js.
page.js looks something like this:
'use client'
import React, { useEffect } from 'react';
const Dashboard = () => {
  useEffect(() => {
    async function fetchData() {
      try {
        const res = await fetch('/api/jobs', {
          method: 'GET',
          headers: {
            'id': '123'
          }
        });
        const data = await res.json();
        console.log("hello", data); // I never hit this console log because the catch below catches the error
      } catch (error) {
        console.log("error")
        console.log(error);
      }
    };
    fetchData();
  }, []);
  
  return (
    <div>
      Hello World
    </div>
  );
}
export default Dashboard;
Then I have my handler located at /app/api/jobs/route.js
route.js looks something like this:
import { NextResponse } from 'next/server';
import { jobs } from "../../../utils/Airtable";
 
export async function GET(req) {
  let headers = await req.headers.get('id'); // this logs out the headers just fine
  let recordsArr = [];
  try {
        jobs.select({
            view: 'Grid view',
            fields: ['Project Lead'],
            filterByFormula: `AND({Project Lead} = 'Jane Doe', AND({Created Day}, '6/1/23'))`
        }).eachPage(function page(records, fetchNextPage) {
                recordsArr.push(...records);
                
                try {
                    fetchNextPage();
                } catch (err) {
                    console.log(err)
                    return;
                };
            }, function done(err) { 
                if (err) {
                    return new NextResponse(JSON.stringify({message: 'Error'})) 
                };
                console.log(recordsArr) // this logs out the records perfectly
                return new NextResponse(JSON.stringify(recordsArr));
        });
    } catch (err) {
        return new NextResponse(JSON.stringify({message: 'Error'}), { status: 500 })
    };
  return new NextResponse(JSON.stringify(obj), { status: 200 });
}
As soon as I comment out the Airtable api call I stop getting the error.
If I move the entire Airtable API call to the client component it works flawlessly. So I think there is something about NextJS that I'm not comprehending.
Appreciate your time.
答案1
得分: 0
你需要为该 ID 使用自定义标头吗?
https://nextjs.org/docs/pages/api-reference/next-config-js/headers
英文:
Could it be that you need to use a custom header for that Id?
https://nextjs.org/docs/pages/api-reference/next-config-js/headers
答案2
得分: 0
我理解你的情况,我之前遇到过完全相同的问题。花了我几个小时才找到问题所在,但最终我找到了解决办法。
你的代码问题在于在返回语句中不必要地使用了 new 关键字。你当前使用了这一行:
return new NextResponse(JSON.stringify(recordsArr));
所以,你应该改为:
return NextResponse(JSON.stringify(recordsArr));
在我的情况下,去掉 new 关键字就足以解决问题。
如果你仍然遇到困难,可以尝试使用较小的代码片段进行调试,或者隔离代码的不同部分,以确定问题的根源。
希望这能解决你的问题!
英文:
I empathize with your situation as I faced the exact same issue a while ago. It took me a couple of hours to pinpoint the problem, but eventually I found the solution.
The issue with your code is the unnecessary use of the new keyword in your return statement. You're currently using this line:
return new NextResponse(JSON.stringify(recordsArr));
So, what you should be doing instead is:
return NextResponse(JSON.stringify(recordsArr));
In my case, removing the new keyword was enough to resolve the issue.
If you're still having trouble, it could be beneficial to debug with a smaller piece of code or to isolate different parts of your code to pinpoint where the problem is originating from.
I hope this resolves your issue!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论