Skip to content
Submitted 10 days ago

Interactive Weather Dashboard with Headless UI Components

accessibility, vue, nuxt, typescript, sass/scss
LVL 3
Nata390
@kristianusdianata
A solution to the Weather app challenge

Solution retrospective


What challenges did you encounter, and how did you overcome them?

Even though this is a relatively small project, I treated it as an opportunity to explore some frontend architectural problems such as derived data management, headless component design, and API request control.

1. Managing derived data without polluting the source data

The weather API response contains quite a lot of nested data, and the UI also has its own state (selected unit, selected location, etc.) that affects how the data should be displayed. Initially, the UI logic started to mix with the raw API data, which made the data flow harder to reason about.

To address this, I separated the data into two layers:

  • Source of Truth (SoT) → stores the raw API response
  • View Model → derived data specifically shaped for the UI

The View Model layer connects the UI state with the API data without mutating the original response. This makes the data flow more predictable and keeps the API data clean.

2. Designing headless UI components while keeping accessibility intact

Another challenge was building headless UI components that remain accessible. Accessibility features such as ARIA attributes, roles, and element relationships often require components to share context with each other. Passing these values through props quickly becomes messy.

To simplify this, I created a provide/inject wrapper (similar to React's useContext) to manage accessibility-related state across components. This allows components to stay decoupled while still sharing the necessary accessibility information.

The result is a flexible headless component structure that is easier to maintain while still supporting accessibility.

3. Preventing race conditions in the combobox search

The location combobox triggers an API request whenever the user types. This introduces a classic race condition problem where older requests might resolve after newer ones. If not handled properly, this could cause outdated results to appear in the UI.

To solve this, I implemented two mechanisms:

  • Debouncing the input to prevent excessive API requests while the user is typing.
  • Assigning a unique request ID to each request so that only the most recent response is allowed to update the UI.

If an older request resolves later, its response is simply ignored.

4. Reducing redundant API requests with client-side caching

Weather data is inherently periodical, meaning it doesn't change very frequently. Continuously requesting the same query would be inefficient.

To handle this, I implemented a simple client-side caching strategy:

  • API responses are cached based on their query.
  • Each cache entry has a TTL of 1 hour.

If the same query is requested again within the TTL window, the application serves the cached response instead of hitting the API again. This approach significantly reduces unnecessary API calls and improves perceived performance.

What specific areas of your project would you like help with?

This project was a bit of an experiment for me. I tried applying several architectural ideas such as separating Source of Truth and View Model, building headless UI components with accessibility, handling race conditions in API requests, and adding a simple client-side caching strategy.

Since this is my first time experimenting with these patterns in a small application like this, I’m curious whether the approaches I used make sense for this type of project, or if they might be considered overengineering.

I’d really appreciate feedback on things like:

  • whether these architectural decisions are reasonable for a project of this size
  • if there are simpler or more idiomatic approaches I might be missing
  • whether there are potential edge cases or bugs that could appear in the current implementation

Any thoughts, critiques, or suggestions for improvement would be really helpful. I'm especially interested in learning how more experienced developers would approach these problems.

Code
Loading...

Please log in to post a comment

Log in

Community feedback

No feedback yet. Be the first to give feedback on Nata’s solution.

Join our Discord community

Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!

Join our Discord