How to use a POST function on onClick in a button without having to use 'use client'?
Answered
Ocicat posted this in #help-forum
OcicatOP
I have this fetching function that I wanna use on a button inside a component, how can I do it without having to change it to a client component? I have a page.tsx file where I'm using a function to fetch the recommendedTracks and then pass the tracks as props to the RecommendationsTable. In this table I also wanna have a button that allows users to create a playlist and add the recommended tracks to it when they click on the button.
export async function addTracksToPlaylist(
accessToken: string,
recommendedTracksData: any
) {
const tracksUri = recommendedTracksData.map((track: any) => track.uri);
const response = await fetch(
`https://api.spotify.com/v1/users/me/playlists`,
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
name: "My Recommendation Playlist",
description: "Playlist created by AudiAura",
public: false,
}),
}
);
if (!response.ok) {
throw new Error("Failed to create playlist");
}
const playlist = await response.json();
await fetch(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ uris: tracksUri }),
});
return playlist;
}Answered by joulev
onClick requires a client component. But you can use a server action instead:
<form action={…}>
<button>Add to playlist</button>
</form>
<form action={…}>
<button>Add to playlist</button>
</form>
4 Replies
@Ocicat I have this fetching function that I wanna use on a button inside a component, how can I do it without having to change it to a client component? I have a page.tsx file where I'm using a function to fetch the recommendedTracks and then pass the tracks as props to the RecommendationsTable. In this table I also wanna have a button that allows users to create a playlist and add the recommended tracks to it when they click on the button.
ts
export async function addTracksToPlaylist(
accessToken: string,
recommendedTracksData: any
) {
const tracksUri = recommendedTracksData.map((track: any) => track.uri);
const response = await fetch(
`https://api.spotify.com/v1/users/me/playlists`,
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
name: "My Recommendation Playlist",
description: "Playlist created by AudiAura",
public: false,
}),
}
);
if (!response.ok) {
throw new Error("Failed to create playlist");
}
const playlist = await response.json();
await fetch(`https://api.spotify.com/v1/playlists/${playlist.id}/tracks`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({ uris: tracksUri }),
});
return playlist;
}
onClick requires a client component. But you can use a server action instead:
<form action={…}>
<button>Add to playlist</button>
</form>
<form action={…}>
<button>Add to playlist</button>
</form>
Answer
@joulev onClick requires a client component. But you can use a server action instead:
<form action={…}>
<button>Add to playlist</button>
</form>
OcicatOP
so something like this?
<form action={addTracksToPlaylist}>
<SubmitBtn />
</form>
<SubmitBtn /> will be a client component so I can use useFormStatus and <RecommendationsTable /> will remain a server component. I've added addTracksToPlaylist to a file called actions.ts which I marked with 'use server'
<form action={addTracksToPlaylist}>
<SubmitBtn />
</form>
<SubmitBtn /> will be a client component so I can use useFormStatus and <RecommendationsTable /> will remain a server component. I've added addTracksToPlaylist to a file called actions.ts which I marked with 'use server'
OcicatOP
I'll try it, but I think I have to modify the function now in order to use it correclty in the form