How would I update a page based on a response?
Answered
Batimius posted this in #help-forum
BatimiusOP
Hello there. I'll do my best to explain this to the best of my ability.
## Ultimate Goal
My main goal is to make a locally-hosted app where you can choose between a few entries and depending on the chosen entries, some algorithms will process the responses and give you a final result. Now, how this works is, you have a pre-defined list of song entries, and every time, you will be asked to pick between two (look at the image below). Once you click "Pick Me", your response will be saved (ideally on the server, but ultimately, it doesn't matter), and the page will "refresh" and give you a new set of songs to choose from. This process repeats until no more choices are available, in which the server then sorts through all submitted choices and gives you a final answer. Think of it as one of those elimination games.
## My Issue
This is where my issue comes in. I am a beginner when it comes to Next.js. I have taken a 7-hour course on YouTube, but that is about it. This is the first "application" that I am making on my own. That said, I am clueless on how I should approach this. I could just send an API request to the backend every time a button is clicked, but what would I do from there? I really can't wrap my head around how I would approach a problem like this, so this is why I turned to the community for help.
## Complex Issues
Now, when making something like this, some issues involving complexity might arise, such as working with multiple clients, progress, etc. The good thing is that this isn't going to be hosted online, and therefore won't accommodate multiple clients. We're working with a single client and the rest doesn't matter. If they want to restart, they can just restart the Next.js app.
## My Code
(Due to character limit, I'll post it right under this message)
## Conclusion
All in all, I have no idea how to approach this. If you could point me to some resources that would help, I would greatly appreciate it. Thank you for the help!
## Ultimate Goal
My main goal is to make a locally-hosted app where you can choose between a few entries and depending on the chosen entries, some algorithms will process the responses and give you a final result. Now, how this works is, you have a pre-defined list of song entries, and every time, you will be asked to pick between two (look at the image below). Once you click "Pick Me", your response will be saved (ideally on the server, but ultimately, it doesn't matter), and the page will "refresh" and give you a new set of songs to choose from. This process repeats until no more choices are available, in which the server then sorts through all submitted choices and gives you a final answer. Think of it as one of those elimination games.
## My Issue
This is where my issue comes in. I am a beginner when it comes to Next.js. I have taken a 7-hour course on YouTube, but that is about it. This is the first "application" that I am making on my own. That said, I am clueless on how I should approach this. I could just send an API request to the backend every time a button is clicked, but what would I do from there? I really can't wrap my head around how I would approach a problem like this, so this is why I turned to the community for help.
## Complex Issues
Now, when making something like this, some issues involving complexity might arise, such as working with multiple clients, progress, etc. The good thing is that this isn't going to be hosted online, and therefore won't accommodate multiple clients. We're working with a single client and the rest doesn't matter. If they want to restart, they can just restart the Next.js app.
## My Code
(Due to character limit, I'll post it right under this message)
## Conclusion
All in all, I have no idea how to approach this. If you could point me to some resources that would help, I would greatly appreciate it. Thank you for the help!
Answered by Aleutian Tern
Merging the 2 points you should have something like this:
import SongEntry from "./components/SongEntry"
export default async function Home() {
const songs = await getSongs()
return (
<>
<h1 className="website-title">Compare Entries</h1>
<div className="entry-container">
<Form initialSongs={songs}/>
</div>
</>
)
async function getSongs() {
const request = await fetch("/fetch-my-songs")
const songs = await api.json()
return songs
}
}10 Replies
BatimiusOP
## My Code
### page.tsx
### SongEntry.tsx
### page.tsx
import SongEntry from "./components/SongEntry"
export default function Home() {
return (
<>
<h1 className="website-title">Compare Entries</h1>
<div className="entry-container">
<SongEntry title="JJK S2 OP2" name="SPECIALZ" artist="King Gnu" embedId="5yb2N3pnztU"></SongEntry>
<SongEntry title="JJK S1 OP1" name="Kaikai Kitan" artist="Eve" embedId="GwaRztMaoY0"></SongEntry>
</div>
</>
)
}### SongEntry.tsx
'use client'
import './SongEntry.css'
import React, {useState} from 'react'
type Props = {
title: string,
name: string,
artist: string,
embedId?: string
}
export default function SongEntry({ title, name, artist, embedId }: Props) {
const [content, setContent] = useState("something")
const changeContents = () => {
setContent("bruh")
}
return (
<div className="entry">
<h2>{title}</h2>
<p>"<u>{name}</u>" - {artist}</p>
{(!embedId) ? undefined :
<div className="iframe-container">
<iframe width="100%" height="100%" frameborder="0" allow="picture-in-picture; fullscreen; autoplay;" style={{borderRadius: "8px", pointerEvents: "auto"}}
src={`https://www.youtube.com/embed/${embedId}`}>
</iframe>
</div>
}
<button onClick={changeContents} className="primary-button primary-text-contrast highlight-toolbar">Pick Me</button>
</div>
)
}Aleutian Tern
I think your proposed approach is very sensible. You can send the request to the backend using Nextjs API and process the data here. You have established how the client and server will communicate, now you need to figure out how to make the server process your algorithm. I think you are missing the bit about storing data. Imagine if you could save the responses for each click, send the new entries and at the final step you retrieve this saved information to create the final answer. You could also start to manipulate the choices at each step. You have a lot of ways to do this, such as using a JSON/Object, a database, cookies, localStorage, etc. In the end, it will only be a matter of storing this information somewhere to retrieve it later or you could do this entirely in the backend and not need to store information on the client-side.
That's basically it, great problem description. Also, one small tip: don't overthink too much. It is good that you can see/think about some problems that can arise from scaling or being online, but in the beginning you don't need to worry too much about these things.
@Aleutian Tern I think your proposed approach is very sensible. You can send the request to the backend using Nextjs API and process the data here. You have established how the client and server will communicate, now you need to figure out how to make the server process your algorithm. I think you are missing the bit about storing data. Imagine if you could save the responses for each click, send the new entries and at the final step you retrieve this saved information to create the final answer. You could also start to manipulate the choices at each step. You have a lot of ways to do this, such as using a JSON/Object, a database, cookies, localStorage, etc. In the end, it will only be a matter of storing this information somewhere to retrieve it later or you could do this entirely in the backend and not need to store information on the client-side.
BatimiusOP
Thank you very much for the reply, time, and help! I am still pondering over how I would update the two entries themselves. Since the amount of choices are porportional to the ones you pick, I can't simply make different pages for each choice pair (since I don't have a pre-defined amount and what you pick changes the next selection) and I have no idea how I would go about updating the two entries to include different information (at least from the server side of things [but to be fair, from the client side of things as well]). I'll try experimenting with setting states, but I am fearing that this might not be the best approach to this problem.
Aleutian Tern
Well you can keep using the same page, and instead of using hardcoded youtube link sources use variables, with that you can update it after each click.
I think a overview what needs to be accomplish is something like this:
I think a overview what needs to be accomplish is something like this:
Get first 2 entries for the first page -> User click -> Send this information to the server -> Server return the new entries Repeat until the final answer / Redirect to the final answer page/section.@Aleutian Tern Well you can keep using the same page, and instead of using hardcoded youtube link sources use variables, with that you can update it after each click.
I think a overview what needs to be accomplish is something like this: `Get first 2 entries for the first page` -> `User click` -> `Send this information to the server` -> `Server return the new entries` Repeat until the final answer / Redirect to the final answer page/section.
BatimiusOP
I kind of understand what you are saying. So you suggest I instead handle the changes on the client and pass the properties of SongEntry as states instead?
Aleutian Tern
Kind, you already have the SongEntry component that dynamically show a card right ? The missing bits is:
- Don't hardcode the entries. For example, on the Home page, you could use some kind of fetch to retrieve the first songs.
2- The cards are shown two by two. I would create another client component to manage retrieving and displaying the songs. This is mainly because the SongEntry component already has well-defined functionality, and you may complicate things if you add too much complex logic to it
- Don't hardcode the entries. For example, on the Home page, you could use some kind of fetch to retrieve the first songs.
import SongEntry from "./components/SongEntry"
export default async function Home() {
const songs = await getSongs()
return (
<>
<h1 className="website-title">Compare Entries</h1>
<div className="entry-container">
<SongEntry {...song[0]}></SongEntry>
<SongEntry {...song[1]}></SongEntry>
</div>
</>
)
async function getSongs() {
const request = await fetch("/fetch-my-songs")
const songs = await api.json()
return songs
}
}2- The cards are shown two by two. I would create another client component to manage retrieving and displaying the songs. This is mainly because the SongEntry component already has well-defined functionality, and you may complicate things if you add too much complex logic to it
function MyForm({initialSongs}) {
const [songs, setSongs] = useState(initialSongs)
// this will the function trigerred when a user select a song
const handleOnclick = async (id: string) => {
// send the selected song to the server
const response = await fetch("/submitSong", {method: 'POST'})
if (response.ok) {
// the server can respond with the new songs to show
const data = await response.json()
// this will update the SongEntries to show the next batch of song to be selected
setSongs(data.songs)
}
}
return (
{songs.map((song) => <SongEntry key={song.id} handeOnClick={() => handleOnClick(song.id)} {...song}/>)}
)
}Aleutian Tern
Merging the 2 points you should have something like this:
import SongEntry from "./components/SongEntry"
export default async function Home() {
const songs = await getSongs()
return (
<>
<h1 className="website-title">Compare Entries</h1>
<div className="entry-container">
<Form initialSongs={songs}/>
</div>
</>
)
async function getSongs() {
const request = await fetch("/fetch-my-songs")
const songs = await api.json()
return songs
}
}Answer
@Aleutian Tern Merging the 2 points you should have something like this:
js
import SongEntry from "./components/SongEntry"
export default async function Home() {
const songs = await getSongs()
return (
<>
<h1 className="website-title">Compare Entries</h1>
<div className="entry-container">
<Form initialSongs={songs}/>
</div>
</>
)
async function getSongs() {
const request = await fetch("/fetch-my-songs")
const songs = await api.json()
return songs
}
}
BatimiusOP
Thank you very much for the help! I implemented this (well, along the lines of this), and now it refreshes dynamically. I did come across some other problems, but those are for another thread. Thank you very much for your help, it is truly appreciated!
@Batimius Thank you very much for the help! I implemented this (well, along the lines of this), and now it refreshes dynamically. I did come across some other problems, but those are for another thread. Thank you very much for your help, it is truly appreciated!
Aleutian Tern
I glad to hear that. Feel free to DM me if you have any other question!