Is there a better way to fetch?
Answered
Yellowstripe scad posted this in #help-forum
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
interface Switch {
id: string;
switch_name: string;
videos: string[];
createdAt: Date;
ended: boolean;
accented: number;
bassy: number;
bouncy: number;
buttery: number;
chirpy: number;
clacky: number;
creamy: number;
crunchy: number;
easy_to_press: number;
feathery: number;
frictionless: number;
gummy: number;
high_pitched: number;
invigorating: number;
low_pitched: number;
marbly: number;
mild: number;
muted: number;
neutral: number;
polished: number;
resonant: number;
sharp: number;
silky: number;
snappy: number;
stepped: number;
stiff: number;
subdued: number;
subtle: number;
textured: number;
thocky: number;
}
export default async function VotePage() {
let switches;
try {
const response = await fetch(process.env.URL + '/api/vote/get_switches', {
method: "POST",
headers: {
"Content-Type": "application/json"
}
});
const data = await response.json();
switches = data.switches;
} catch (error) {
console.error("Error:", error);
}
return (
<div>
{switches && switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))}
</div>
);
}
I was just wondering if I should use useEffect or useState, it works fine but I feel like im missing something to make it better. any suggestions?
Answered by Yellowstripe scad
app/vote/page.tsx
"use client"
import { useState, useEffect } from 'react'
import { Switch } from "@/lib/types";
export default function VotePage() {
const [foundSwitches, setFoundSwitches] = useState({ switches: [] });
useEffect(()=> {
const getData = async () => {
const query = await fetch("/api/vote/get_switches")
const response = await query.json()
console.log("response from API: ", response)
setFoundSwitches(response)
}
getData()
}, [])
return (
<div>
{foundSwitches.switches.length > 0 ? (
foundSwitches.switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))
) : (
<p>No switches found</p>
)}
</div>
)
}
app/api/vote/get_switches
import { db } from "@/lib/db";
import { NextResponse } from "next/server";
export async function GET(req: Request) {
try {
const foundSwitches = await db.preVotingSwitches.findMany();
if (!foundSwitches) {
return NextResponse.json({ switch: null, message: "No switches found" }, { status: 404 });
}
return NextResponse.json({ switches: foundSwitches, message: "All Switches found" }, { status: 200 });
} catch (error) {
console.error("Error:", error); // Log the error for debugging
return NextResponse.json({ message: "Something went wrong!" }, { status: 500 });
}
}
37 Replies
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Yes, absolutely, you can can call the fetch in function called
I think it's more correct then using fetch like you've done because if you check the console I bet it is called more then one time
getSwitchs()
inside useEffect to fetch and useState to affect to a variable of type array of switchsI think it's more correct then using fetch like you've done because if you check the console I bet it is called more then one time
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
thank you so much lmao, brand new to nextjs and dont even know what those two do!
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Ah okey, so in fact they are hooks basically used in React then as Next.js is a framework based on it you can use them
So useEffect is called once when the page is loaded
useState you probably know a little bit about it it's to manage a state which is a sort of variable
So useEffect is called once when the page is loaded
useState you probably know a little bit about it it's to manage a state which is a sort of variable
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
I see, my code here loads forever, dont know why. I dont think I ever call the useEffect or something to actually send the request. how can I fix it:
I was using this to try and do it:
https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side
"use client"
import { useState, useEffect } from 'react'
import { Switch } from "@/lib/types";
export default async function VotePage() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(true)
useEffect(() => {
fetch(process.env.URL + '/api/vote/get_switches', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
})
.then((res) => res.json())
.then((data) => {
setData(data)
setLoading(false)
})
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No profile data</p>
return (
<div>
{/* {data &&
data.switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))} */}
{data && data}
</div>
);
}
I was using this to try and do it:
https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
isLoading should be false by default in default value of the useState because it doesn't load by default it's logical
So you have to set it to true before the call to fetch inside useEffect
So you have to set it to true before the call to fetch inside useEffect
Also you have a POST method set it to GET
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
thanks
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Thank me when it is fixed 😉
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
I want it to be post, im fetching data, this is also just loading forever
![Image](https://cdn.discordapp.com/attachments/1188921297611268146/1188948060932415518/image.png?ex=659c612b&is=6589ec2b&hm=8c949aba8173677be5022f6420e215d23bcb8101f30803e32cb50a9491594d03&)
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Yeah but POST is for posting data not GETing it
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
I thought get was for displaying pages
/api/vote/get_switches
async function GET(req: Request) {
try {
const foundSwitches = await db.preVotingSwitches.findMany();
if (!foundSwitches) {
return NextResponse.json({ switch: null, message: "No switches found" }, { status: 404 });
}
return NextResponse.json({ switches: foundSwitches, message: "All Switches found" }, { status: 200 });
} catch (error) {
console.error("Error:", error); // Log the error for debugging
return NextResponse.json({ message: "Something went wrong!" }, { status: 500 });
}
}
/vote/page.tsx
"use client"
import { useState, useEffect } from 'react'
import { Switch } from "@/lib/types";
export default function VotePage() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
fetch(process.env.URL + '/api/vote/get_switches', {
method: "GET",
headers: {
"Content-Type": "application/json"
},
})
.then((res) => res.json())
.then((data) => {
setData(data)
setLoading(false)
})
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No profile data</p>
return (
<div>
{/* {data &&
data.switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))} */}
{data && data}
</div>
);
}
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
try it like this it seems okey
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
it just says "Loading..." forever
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Try to put
setLoading(false)
just after the call"use client"
import { useState, useEffect } from 'react'
import { Switch } from "@/lib/types";
export default function VotePage() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
fetch(process.env.URL + '/api/vote/get_switches', {
method: "GET",
headers: {
"Content-Type": "application/json"
},
})
.then((res) => res.json())
.then((data) => {
setData(data)
})
setLoading(false)
}, [])
if (isLoading) return <p>Loading...</p>
if (!data) return <p>No profile data</p>
return (
<div>
{data && data.switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))}
</div>
);
}
btw, you'll have an error about the typing of the useState that should be an array of Switchs
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
right now im having a problem with my route, I made it into this:
but neither of the "here"s get logged
import { db } from "@/lib/db";
import { NextResponse } from "next/server";
export async function GET(req: Request) {
try {
const foundSwitches = await db.preVotingSwitches.findMany();
if (!foundSwitches) {
console.log("here 2")
return NextResponse.json({ switch: null, message: "No switches found" }, { status: 404 });
}
console.log("here")
return NextResponse.json({ switches: foundSwitches, message: "All Switches found" }, { status: 200 });
} catch (error) {
console.error("Error:", error); // Log the error for debugging
return NextResponse.json({ message: "Something went wrong!" }, { status: 500 });
}
}
but neither of the "here"s get logged
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
So why it was working before ?
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
in the route I changed it to GET
nothing gets returned I think
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Try to call this endpoint
without GET in the header you see
Like this
https://www.youtube.com/watch?v=GM6Uvp0BWVE
https://jsonplaceholder.typicode.com/users
without GET in the header you see
Like this
https://www.youtube.com/watch?v=GM6Uvp0BWVE
Then if it works we'll try to fix the API part 🙂
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Also if the API is called inside your Next.js app normally you don't need to provide an url so I don't know if it is in the same project
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
this works, copied down the code
let me try adjusting it to my route
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
So if this works it's cool
I think the problem comes from the call with the url, try to not add the
process.env.URL
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
oohhh maybeee
u might be right
I only added that for my nextauth
![Avatar](https://cdn.discordapp.com/embed/avatars/5.png)
Pond loach
Yeah because it's like an external call to the API
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
ok I've got it all working
had to ask chatgpt to fix it but it only added
useState({ switches: [] })
from useState({})
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
app/vote/page.tsx
"use client"
import { useState, useEffect } from 'react'
import { Switch } from "@/lib/types";
export default function VotePage() {
const [foundSwitches, setFoundSwitches] = useState({ switches: [] });
useEffect(()=> {
const getData = async () => {
const query = await fetch("/api/vote/get_switches")
const response = await query.json()
console.log("response from API: ", response)
setFoundSwitches(response)
}
getData()
}, [])
return (
<div>
{foundSwitches.switches.length > 0 ? (
foundSwitches.switches.map((switchItem: Switch) => (
<p key={switchItem.id}>{switchItem.id}</p>
))
) : (
<p>No switches found</p>
)}
</div>
)
}
app/api/vote/get_switches
import { db } from "@/lib/db";
import { NextResponse } from "next/server";
export async function GET(req: Request) {
try {
const foundSwitches = await db.preVotingSwitches.findMany();
if (!foundSwitches) {
return NextResponse.json({ switch: null, message: "No switches found" }, { status: 404 });
}
return NextResponse.json({ switches: foundSwitches, message: "All Switches found" }, { status: 200 });
} catch (error) {
console.error("Error:", error); // Log the error for debugging
return NextResponse.json({ message: "Something went wrong!" }, { status: 500 });
}
}
Answer
![Avatar](https://cdn.discordapp.com/embed/avatars/0.png)
Yellowstripe scadOP
ty!