Enjoy 20% off all plans by following us on social media. Check out other promotions!

Job Board Solution

Author
Michal GrzegorczykSenior Front End Engineer, Ofair
Languages
HTMLCSSJS

Solution

Firstly, in ngOnInit() hook, we will utilize the HttpClient service to initially load all job ids, save them to a property named allJobIds and subsequently call the fetchJobs() function to retrieve the first job contents.

Within the fetchJobs() function, we will determine the job ids to be loaded, using the PAGE_SIZE constant so every time we call fetchJobs() we will load the next job contents and if ids property will be empty it won't be executed in forkJoin.

We will initiate requests equivalent to the number indicated by ids.length and using forkJoin, an array of the loaded jobs will be returned. Subsequently, we will update the jobs with the newly loaded ones using the spread operator.

State

The code utilizes several state variables to manage the application's behavior and data flow:

  • fetchingJobDetails: This state variable keeps track of whether job details are currently being fetched from the API. It is used to disable the "Load more" button and provide feedback to the user during the fetching process.
  • jobIds: This state variable stores an array of job IDs retrieved from the Hacker News API. It is initially set to null and later populated with data from the API. It allows for pagination and fetching job details based on the IDs.
  • jobs: This state variable maintains an array of job objects containing details like job title, author, time, and URL. It is initially null and is updated when fetching job details from the API.
  • page: This state variable keeps track of the current page number, determining which set of job IDs and details to fetch. It is incremented when the user clicks on the "Load more" button.

Rendering

Some notable aspects of the rendering code include:

  • The use of CSS Grid for the list of posts: The job postings are displayed in a grid layout using the display: grid CSS property. This is a convenient way to allow consistent spacing between job postings.
  • Styling of the "Load more" button: The "Load more" button is styled with a specific background color, border, and padding to make it visually prominent. The button also changes color on hover to provide visual feedback to the user.

Models

export interface Job {
url: string;
title: string;
by: string;
time: number;
}

Angular Insights

  • You can adopt a more advanced, reactive-like approach using RxJS (without using subscriptions as possible). However, if you opt for subscriptions, remember about destroying them to prevent memory leaks.

  • You might create services for HTTP requests and another service for maintaining the state.

  • If you're confident with the latest Angular versions, consider using signals standalone API.

  • You can try to focus more on keywords such as readonly, private, public and void.

  • If you're creating a bigger application it would be good practice to use styles per component instead of putting all styles in one file.

Test Cases

  1. Initial Loading: Verify that when the page loads, the message "Loading..." is displayed until the job IDs are fetched from the Hacker News API.
  2. Job Postings: Once the job IDs are fetched, check that the job postings are rendered correctly. Verify that the job title, poster, and timestamp are displayed accurately for each job posting.
  3. Click on a job title and ensure that it opens the correct URL in a new tab or window if there's a url field in the job details.
  4. Pagination: Click the "Load more" button and verify that additional job postings are fetched and displayed. Repeat this step multiple times to ensure that pagination works correctly.
  5. Button State: Check that the "Load more" button is disabled while job details are being fetched to prevent multiple requests. Verify that the button becomes enabled again once the fetching process is complete.
  6. Keyboard Navigation: Use only the keyboard to navigate through the job postings and interact with the "Load more" button. Ensure that all interactive elements are accessible and usable without requiring a mouse.

Notes

  • Note that we aren't handling any API failure cases here. It'd be good for you to handle them!