Build blog UI with API data and likes
Problem Description
You are tasked with implementing a small single-page web application (SPA) in JavaScript to display and interact with a list of blog posts. You may use any modern framework or plain JavaScript. The implementation should be completed in four incremental levels.
Data Model
Initially, you will use a local JSON file (posts.json) containing an array of blog posts. For later levels, assume a backend exposes the following HTTP endpoints, all returning JSON. Network requests can fail.
// posts.json structure and GET /api/posts response
[
{
"id": 1,
"title": "First post",
"body": "Hello world",
"authorId": 101,
"likes": 3
},
{
"id": 2,
"title": "Second post",
"body": "Another post",
"authorId": 102,
"likes": 5
}
]
// GET /api/authors/:id response
{
"id": 101,
"name": "Alice"
}
// GET /api/me response
{
"id": 101
}
Level 1: Render Posts from Local JSON
- Load the posts from the local
posts.jsonfile. - Render a list of blog posts to the page.
- For each post, display at least the title and body.
- Author information or likes are not required at this level.
Level 2: Add a Form to Create Posts
Extend the page with the ability to add new blog posts on the client side.
- Add a form with the following inputs:
title(text)body(multi-line text)
- When the user submits the form:
- Create a new post object with a unique
id(client-generated), an arbitraryauthorId, andlikes = 0. - Append it to the existing list of posts without reloading the page.
- Create a new post object with a unique
- Clear the form after successful submission.
Note: New posts do not need to be persisted to a backend; client-side state management is sufficient.
Level 3: Replace Local JSON with API Calls and Show Authors
Replace the local JSON source with remote API calls and enhance post display.
- On page load, fetch all posts from
GET /api/posts. - For each post, fetch its author information from
GET /api/authors/:idusing theauthorIdfrom the post.- Fetch these author details in parallel/asynchronously (do not block on one author before starting the next if possible).
- Fetch the current user from
GET /api/me. - In the UI, for each post:
- Display the post's title and body.
- Display the author label:
- If the post's
authorIdmatches the current user'sid(from/api/me), displayYou. - Otherwise, display the author's
namereturned by/api/authors/:id.
- If the post's
- Implement basic loading and error handling:
- Show a loading state while posts are being fetched.
- If fetching posts fails, show an error message instead of the list.
- If fetching an individual author fails, still show the post but display
Unknown author.
Assumption: GET /api/posts and GET /api/authors/:id can be called concurrently and may resolve in any order.
Level 4: Add Likes and Keep Posts Sorted by Likes
Add an interactive "Like" feature to each post.
- For each rendered post, display:
- The current number of likes (from its
likesfield). - A
Likebutton.
- The current number of likes (from its
- When the user clicks the
Likebutton on a post:- Increment that post's
likescount in the UI immediately (no page reload). - Re-sort the list of posts on the client so that posts are always displayed in descending order of likes (most liked first).
- Increment that post's
- The sorting should update dynamically after each click.
Note: Likes do not need to be persisted to the backend; client-side state management is sufficient. Focus on correct UI behavior, state management, concurrency of API calls, and error handling.
AI interview prep
Core dilemma
Managing complex, interdependent client-side state derived from multiple asynchronous API calls, while maintaining UI responsiveness, consistency, and dynamic sorting without backend persistence.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Build blog UI with API data and likes
Problem Description
You are tasked with implementing a small single-page web application (SPA) in JavaScript to display and interact with a list of blog posts. You may use any modern framework or plain JavaScript. The implementation should be completed in four incremental levels.
Data Model
Initially, you will use a local JSON file (posts.json) containing an array of blog posts. For later levels, assume a backend exposes the following HTTP endpoints, all returning JSON. Network requests can fail.
// posts.json structure and GET /api/posts response
[
{
"id": 1,
"title": "First post",
"body": "Hello world",
"authorId": 101,
"likes": 3
},
{
"id": 2,
"title": "Second post",
"body": "Another post",
"authorId": 102,
"likes": 5
}
]
// GET /api/authors/:id response
{
"id": 101,
"name": "Alice"
}
// GET /api/me response
{
"id": 101
}
Level 1: Render Posts from Local JSON
- Load the posts from the local
posts.jsonfile. - Render a list of blog posts to the page.
- For each post, display at least the title and body.
- Author information or likes are not required at this level.
Level 2: Add a Form to Create Posts
Extend the page with the ability to add new blog posts on the client side.
- Add a form with the following inputs:
title(text)body(multi-line text)
- When the user submits the form:
- Create a new post object with a unique
id(client-generated), an arbitraryauthorId, andlikes = 0. - Append it to the existing list of posts without reloading the page.
- Create a new post object with a unique
- Clear the form after successful submission.
Note: New posts do not need to be persisted to a backend; client-side state management is sufficient.
Level 3: Replace Local JSON with API Calls and Show Authors
Replace the local JSON source with remote API calls and enhance post display.
- On page load, fetch all posts from
GET /api/posts. - For each post, fetch its author information from
GET /api/authors/:idusing theauthorIdfrom the post.- Fetch these author details in parallel/asynchronously (do not block on one author before starting the next if possible).
- Fetch the current user from
GET /api/me. - In the UI, for each post:
- Display the post's title and body.
- Display the author label:
- If the post's
authorIdmatches the current user'sid(from/api/me), displayYou. - Otherwise, display the author's
namereturned by/api/authors/:id.
- If the post's
- Implement basic loading and error handling:
- Show a loading state while posts are being fetched.
- If fetching posts fails, show an error message instead of the list.
- If fetching an individual author fails, still show the post but display
Unknown author.
Assumption: GET /api/posts and GET /api/authors/:id can be called concurrently and may resolve in any order.
Level 4: Add Likes and Keep Posts Sorted by Likes
Add an interactive "Like" feature to each post.
- For each rendered post, display:
- The current number of likes (from its
likesfield). - A
Likebutton.
- The current number of likes (from its
- When the user clicks the
Likebutton on a post:- Increment that post's
likescount in the UI immediately (no page reload). - Re-sort the list of posts on the client so that posts are always displayed in descending order of likes (most liked first).
- Increment that post's
- The sorting should update dynamically after each click.
Note: Likes do not need to be persisted to the backend; client-side state management is sufficient. Focus on correct UI behavior, state management, concurrency of API calls, and error handling.