Points of interest —
Server
server/apollo/schema.js
server/apollo/resolvers.js
[ ] Since we already have the Playlist
and Media
types, we can move right into the resolvers we need to create and delete playlists.
createPlaylist: async (_, args, { prisma }) => {
const playlist = prisma.createPlaylist({
owner: {
connect: {
id: args.userId
}
},
title: args.title
});
return playlist;
},
deletePlaylist: async (_, args, { prisma }) => {
const deletePlaylist = await prisma.updateUser({
data: { playlists: { delete: { id: args.playlistId } } },
where: {
id: args.userId
}
});
return deletePlaylist;
},
and in our schema.js
type Mutation {
...
## Playlist Mutations
createPlaylist(userId: ID!, media: MediaInput, title: String!): Playlist
deletePlaylist(playlistId: ID!, userId: ID!): SuccessMessage
}
Points of interest
Client
Components of interest —
PlaylistForm.js
Playlist.js
PlaylistForm
import React from "react";
import { useMutation, useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
import CURRENT_USER from "../Auth/CurrentUser";
// Mutation constant
const CREATE_PLAYLIST = gql`
mutation CreatePlaylist($userId: ID!, $title: String!) {
createPlaylist(userId: $userId, title: $title) {
title
id
}
}
`;
const PlaylistForm = () => {
// track the state of the input
const [playlist, setPlaylist] = React.useState({
title: ""
});
// by creating and attaching a ref to the input,
// we can hook into the input and reset it
const inputRef = React.useRef();
const { data } = useQuery(CURRENT_USER);
const [createPlaylist] = useMutation(CREATE_PLAYLIST, {
// we brought up refetchQueries earlier. this will allow us to
// re render the component with the updated user data, meaning wherever
// we are rendering the playlists using the CURRENT_USER query, it will
// now update and re render the component
refetchQueries: () => [{ query: CURRENT_USER, variables: {} }]
});
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
createPlaylist({
variables: {
title: playlist.title,
userId: data.currentUser.id
}
});
inputRef.current.value = "";
}}
>
<div>
<input
onChange={e => setPlaylist({ ...playlist, title: e.target.value })}
ref={inputRef}
/>
<button> + </button>
</div>
</form>
</div>
);
};
export default PlaylistForm;
Playlist
import React from "react";
import { useMutation } from "@apollo/react-hooks";
import gql from "graphql-tag";
import CURRENT_USER from "../Auth/CurrentUser/index";
const DELETE_PLAYLIST = gql`
mutation DeletePlaylist($userId: ID!, $playlistId: ID!) {
deletePlaylist(userId: $userId, playlistId: $playlistId) {
message
}
}
`;
const Playlist = ({ playlist, userId }) => {
const [deletePlaylist] = useMutation(DELETE_PLAYLIST, {
refetchQueries: () => [{ query: CURRENT_USER, variables: {} }]
});
return (
<div>
<h1>{playlist.title}</h1>
<button
onClick={() =>
deletePlaylist({
variables: {
userId: userId,
playlistId: playlist.id
}
})
}
>
Delete
</button>
</div>
);
};
export default Playlist;
Landing
// We will add a component called Playlists to the auth'd landing page
const Playlists = ({ currentUser }) => {
return currentUser ?
currentUser.playlists.map(playlist => (
<Playlist key={playlist.id} userId={currentUser.id} playlist={playlist} />
)) : null;
}
// we will also have to change the render of the landing page to include
// the playlists
const Landing = ({ currentUser }) => {
return (
<div>
<div>
// We will need to pass the current user in, that way
// the component rerenders will be controller by the CURRENT_USER query
<Playlists currentUser={currentUser} />
</div>
</div>
)
}