Overarching Project
It’s again time to continue with the overarching project. In this part, you’ll focus on integrating the server-side and client-side functionality of the “Reddit”-themed overarching project.
We recommend working on the overarching project only after completing all other assignments in this part. For deeper learning, it can also help to take a short break of a few days before starting the project.
In the seventh step, you will build client-side functionality for interacting with server-side APIs for managing communities. You will also remove any localStorage-specific data related to communities.
WSD Overarching Project, Step 7
0 / 40 points
In this step, you will implement a set of client-side community-related APIs, use them to replace the localStorage-based shared state, and introduce a form-based approach for adding new communities. By the end of this step, your client-side application should:
- Allow adding communities using a form and form submission events.
- Use a set of client-side community-related APIs within the community shared state.
- No longer use localStorage for storing community data — instead, it should depend on the server-side database through API calls.
Note: The post data should still be stored in shared state and localStorage. You will modify post-related functionality in a later project step.
Tasks
The task is divided into several parts to help structure your work. Each part focuses on a different component or module with its own responsibilities.
communitiesApi.js
Create a file communitiesApi.js in the src/lib/apis folder. This file should export functions that handle API interactions related to communities, corresponding to the following endpoints:
GET /api/communities→ returns all communities from the database.GET /api/communities/:communityId→ returns a single community by its ID.POST /api/communities→ creates a new community and returns the created community.DELETE /api/communities/:communityId→ deletes a community by its ID and returns the deleted community.
Example data structure for a community:
{ "id": 1, "name": "Community Name", "description": "Community Description", "created_at": "2025-01-01T12:45:00.000Z"}For more details about these API endpoints, refer to the Overarching Project Step 4 instructions.
communityState.svelte.js
Update the existing communityState.svelte.js file by removing all use of localStorage. Modify the shared community state so that it depends entirely on the API module for managing community data.
Add functions to:
- Initialize all communities by fetching them from the API.
- Initialize a single community by its ID from the API.
- Add and delete communities through API calls, updating the shared state accordingly.
AddCommunity.svelte
This component should be deleted, as community creation will now be handled through the new CommunityForm.svelte component.
CommunityForm.svelte
Create a new file CommunityForm.svelte in the src/lib/components/communities folder. This component should provide the following functionality:
-
A form containing:
- An input field of type
textwith the placeholderCommunity nameand thenameattribute set to"name". - A textarea field with the placeholder
Community descriptionand thenameattribute set to"description". - A submit button with the text “Add community” inside the form.
- An input field of type
-
When the form is submitted:
- Prevent the default browser form submission behavior to avoid page reload.
- Retrieve input values and call the shared state function to create a new community using the API.
- Reset the form fields after successful submission.
- Update the UI in real time to show the newly added community in the list.
Communities page (src/routes/communities/+page.svelte)
Update the +page.svelte file to include the following functionality:
- Fetch communities from the API by calling the initialization function in the shared community state when the page loads.
- Use the form to add communities through the API, updating the shared state dynamically.
- Support community deletion through the API, updating the shared state accordingly.
- Ensure that clicking a community name navigates to its individual community page.
Individual community page (src/routes/communities/[communityId]/+page.svelte)
Update the +page.svelte file to:
- Fetch the individual community using the API by calling the relevant initialization function in the shared state.
- Replace any synchronous operations with asynchronous API-based logic.
- Retain existing post-related components and logic, as posts will still rely on localStorage at this stage.
Additional Note
If not already present, create a .env.development file in your client project root and define an environment variable PUBLIC_API_URL with the base URL of your server-side API (e.g., http://localhost:8000).
Ensure that your server-side API has CORS middleware configured so the client can communicate with it during local testing.
Submission
Once ready, zip the contents of your client/src folder and submit the zip file below. The routes folder should be at the root of the zip file. Follow the file and folder names exactly, as the automated tests depend on them.
Expected file structure:
.├── lib│ └── apis│ │ └── communitiesApi.js (new)│ ├── components│ │ └── communities│ │ ├── AddCommunity.svelte (deleted)│ │ ├── Community.svelte (updated)│ │ ├── CommunityForm.svelte (new)│ │ └── ...│ │ └── ...│ └── states│ ├── communityState.svelte.js (updated)│ └── postState.svelte.js└── routes └── communities ├── +page.svelte # Communities page └── [communityId] ├── +page.svelte (updated) # Individual community page └── posts └── [postId] └── +page.svelte (updated) # Individual post pageIn the eight step, you’ll continue building client-side functionality for interacting with server-side APIs, this time for managing posts. You will also remove any localStorage-specific data related to posts.
WSD Overarching Project, Step 8
0 / 40 points
In this step, you will implement a set of client-side post-related APIs, use them to replace the localStorage-based shared state, and introduce a form-based approach for adding posts. By the end of this step, your client-side application should:
- Allow adding posts using a form and form submission events.
- Use a set of client-side post-related APIs within the shared post state.
- No longer use localStorage for storing post data — instead, it should depend on the server-side database through API calls.
Tasks
The task is divided into several parts to help structure your work. Each part focuses on a different component or module with its own responsibilities.
postsApi.js
Create a file postsApi.js in the src/lib/apis folder. This file should export functions that handle API interactions related to posts, corresponding to the following endpoints:
GET /api/communities/:communityId/posts→ returns all posts for a given community from the database.GET /api/communities/:communityId/posts/:postId→ returns a single post by its ID.POST /api/communities/:communityId/posts→ creates a new post for a given community and returns the created post.DELETE /api/communities/:communityId/posts/:postId→ deletes a post by its ID and returns the deleted post.
Example data structure for a post:
{ "id": 1, "title": "Post Title", "content": "Post Content", "community_id": 1, "parent_post_id": null, "created_at": "2025-01-01T12:45:00.000Z"}For more details about these API endpoints, refer to the Overarching Project Step 5 instructions.
postState.svelte.js
Update the existing postState.svelte.js file by removing all use of localStorage. Modify the shared post state so that it depends entirely on the API module for managing post data.
Add functions to:
- Initialize all posts for a given community by fetching them from the API.
- Initialize a single post by its ID from the API.
- Add and delete posts through API calls, updating the shared state accordingly.
AddPost.svelte
This component should be deleted, as post creation will now be handled through the new PostForm.svelte component.
PostForm.svelte
Create a new file PostForm.svelte in the src/lib/components/posts folder. This component should provide the following functionality:
-
A form containing:
- An input field of type
textwith the placeholderPost titleand thenameattribute set to"title". - A textarea field with the placeholder
Post contentand thenameattribute set to"content". - A submit button with the text “Add post” inside the form.
- An input field of type
-
When the form is submitted:
- Prevent the default browser form submission behavior to avoid a page reload.
- Retrieve input values and call the shared state function to create a new post using the API.
- Reset the form fields after successful submission.
- Update the UI in real time to show the newly added post in the list.
Individual community page (src/routes/communities/[communityId]/+page.svelte)
Update the +page.svelte file to include the following functionality:
- Fetch the individual community and its posts from the API by calling initialization functions in the respective shared states when the page loads.
- Add posts using the form and submit them through the API, updating the shared state dynamically.
- Support post deletion through the API, updating the shared state accordingly.
- Ensure that clicking a post title navigates to the individual post page.
Individual post page (src/routes/communities/[communityId]/posts/[postId]/+page.svelte)
Update the +page.svelte file to:
- Fetch the individual post using the API by calling the relevant initialization function in the post shared state.
- Replace any synchronous logic with asynchronous API-based functionality for loading post data.
Submission
Once ready, zip the contents of your client/src folder and submit the zip file below. The routes folder should be at the root of the zip file. Follow the file and folder names exactly, as the automated tests depend on them.
Your project may include additional files (e.g., Dockerfile, deno.json).
Expected file structure:
.├── lib│ └── apis│ │ ├── communitiesApi.js│ │ └── postsApi.js (new)│ ├── components│ │ ├── communities│ │ │ └── ...│ │ └── posts│ │ ├── AddPost.svelte (deleted)│ │ ├── Post.svelte (updated)│ │ ├── PostForm.svelte (new)│ │ └── ...│ └── states│ ├── communityState.svelte.js│ └── postState.svelte.js (updated)└── routes └── communities ├── +page.svelte # Communities page └── [communityId] ├── +page.svelte (updated) # Individual community page └── posts └── [postId] └── +page.svelte (updated) # Individual post pageIn the ninth step, you’ll add the functionality for commenting on posts. This will involve creating a new component for displaying and adding comments, as well as integrating it with the existing post functionality.
WSD Overarching Project, Step 9
0 / 40 points
In this step, you will implement a set of comment-related APIs, create a shared state for managing comments, and develop components for displaying and adding comments on the client side. By the end of this step, your application should include the following new functionality:
- A set of client-side comment APIs used in the shared state.
- A shared state for managing comments.
- Listing all comments for a post.
- Adding and deleting comments.
Each comment should have the following fields:
id: A unique identifier for the comment within its post.title: Always default to the value of `null`.content: The content of the comment.community_id: The identifier of the community to which the comment belongs.parent_post_id: The identifier of the post to which the comment belongs.created_at: The time when the comment was created.In commentState.svelte.js, comments should be stored per post in a shared state object, where each key is a post ID and the value is an array of comment objects. Below is an example of such a structure:
let commentState = $state({ 1: [ { id: 1, title: null, content: "You should test your code locally more", community_id: 1, parent_post_id: 1, created_at: "2025-10-02T00:00:00.000Z" }, ], 2: [ { id: 1, title: null, content: "WSD course of Aalto uni is a great way to start", community_id: 1, parent_post_id: 2, created_at: "2025-01-01T00:00:00.000Z" }, ],});Tasks
The task is divided into parts to help structure your work. Each part corresponds to a specific module or component with its own responsibilities.
commentsApi.js
Create a file commentsApi.js in the src/lib/apis folder. This file should export functions for interacting with the comment-related APIs you implemented in earlier overarching project steps.
The API endpoints are as follows:
GET /api/communities/:communityId/posts/:postId/comments→ returns all comments for a given post and community from the database.POST /api/communities/:communityId/posts/:postId/comments→ creates a new comment for a given post and community, returning the created comment.DELETE /api/communities/:communityId/posts/:postId/comments/:commentId→ deletes a comment by its ID and returns the deleted comment.
Example data format for a comment:
{ "id": 1, "title": null, "content": "Post Content", "community_id": 1, "parent_post_id": 1, "created_at": "2025-01-01T12:45:00.000Z"}For more details about these API endpoints, refer to the Overarching Project Step 6 instructions.
commentState.svelte.js
Create a file commentState.svelte.js in the src/lib/states folder. This file should provide functionality for adding, listing, and deleting comments, along with a function to initialize all comments for a given post and community.
When performing comment operations, always handle them per community and per post — meaning both communityId and postId should be passed when calling these functions.
All comment data should be managed using the API module (no localStorage).
CommentList.svelte
Create a file CommentList.svelte in the src/lib/components/comments folder (create any missing folders). This component should provide the following functionality:
- Accept two properties:
communityIdandpostId, used to retrieve comment data for a specific post and community. - Display a list of all comments belonging to that post using data from
commentState.svelte.js. - Each list item should display the comment’s content.
- Each comment should include a “Remove” button inside its
lielement. Clicking the button should delete the comment through the API and update the UI in real time (no page reload).
CommentForm.svelte
Create a file CommentForm.svelte in the src/lib/components/comments folder. This component should provide the following functionality:
-
A form containing:
- A textarea field with the placeholder
"Comment content"and thenameattribute"content".
- A textarea field with the placeholder
-
A submit button with the text “Add comment” inside the form.
-
When the form is submitted:
- Prevent the default browser form submission to avoid page reload.
- Retrieve the value from the textarea and call the shared state function to create a new comment using the API.
- Reset the form field after successful submission.
- Update the UI in real time to show the newly added comment in the list.
Individual post page (src/routes/communities/[communityId]/posts/[postId]/+page.svelte)
Update the +page.svelte file so that it includes the following functionality:
- Fetch all comments for the post by calling the initialization function from the shared comment state when the page loads.
- Import and display both
CommentForm.svelteandCommentList.svelte, passingcommunityIdandpostIdas props to both components.
After implementing these components, you should be able to list, add, and delete comments for an individual post at
/communities/[communityId]/posts/[postId].
Submission
Once ready, zip the contents of your client/src folder and submit the zip file below. The routes folder should be at the root of the zip file. Follow the file and folder names exactly, as automated tests depend on them.
Your project may include additional files (e.g., Dockerfile, deno.json).
Expected file structure:
.├── lib│ └── apis│ │ ├── commentsApi.js (new)│ │ └── ...│ ├── components│ │ └── comments│ │ ├── CommentForm.svelte (new)│ │ └── CommentList.svelte (new)│ │ └── ...│ └── states│ ├── commentState.svelte.js (new)│ └── ...└── routes └── communities ├── +page.svelte # Communities page └── [communityId] ├── +page.svelte # Individual community page └── posts └── [postId] └── +page.svelte (updated) # Individual post page