Problem Statement
You are given two asynchronous API functions:
getTemperatureData(day)
— returns aPromise
resolving to an object mapping cities to temperature data.getRainData(day)
— returns aPromise
resolving to an object mapping cities to rainfall data, but fails every alternate time it’s called (counter % 2 === 0
) and takes up to 3 seconds to respond.
Both functions accept a day
string (e.g. "2024-07-17"
).
The goal is to display merged data in the following format for each city:
Seattle - 75 22
San Mateo - 80 15
Austin - 90 30
Where each line contains:
-
If getRainData()
fails, just omit rainfall from the output:
Seattle - 75
San Mateo - 80
Austin - 90
Constraints
- Rain data is not guaranteed.
- Do not block UI for 3 seconds if rain fails — be resilient and render what you can.
- You may use React or vanilla JS.
Mock Data:
// mockData.js
let rainCounter = 0;
export function getRainData(day) {
return new Promise((resolve, reject) => {
setTimeout(() => {
rainCounter++;
if (rainCounter % 2 === 0) {
reject(new Error(“Rain API failed”));
} else {
resolve({
Seattle: 13 + day,
“San Mateo”: 25 + day,
Austin: 8 + day,
});
}
}, 3000 * Math.random());
});
}
export function getTemperatureData(day) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
Seattle: 103 + day,
“San Mateo”: 84 + day,
Austin: 91 + day,
});
}, 500 * Math.random());
});
}
Potential Solution:
// WeatherComponent.jsx
import React, { useEffect, useState } from “react”;
import “./App.css”;
import { getRainData, getTemperatureData } from “./mockData”;
function App() {
const [rainData, setRainData] = React.useState({});
const [temperatureData, setTemperatureData] = React.useState({});
const [rainError, setRainError] = React.useState(null);
const [tempError, setTempError] = React.useState(null);
const [loading, setLoading] = React.useState(false);
const fetchData = async () => {
console.log(‘fetchData called at:’, new Date().toISOString());
try {
setLoading(true);
const [rainInfo, tempInfo] = await Promise.allSettled([
getRainData(),
getTemperatureData(),
]);
if (rainInfo.status === 'fulfilled') {
setRainData(rainInfo.value);
setRainError(null);
} else {
setRainError('Rain data fetch failed');
}
if (tempInfo.status === 'fulfilled') {
setTemperatureData(tempInfo.value);
setTempError(null);
} else {
setTempError('Temperature data fetch failed');
}
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, );
const displayMap = new Map();
for (const city in rainData) {
displayMap.set(city, {
rain: rainData[city],
temperature: temperatureData[city] || ‘N/A’,
});
}
return (
Weather Data Fetching Example
{loading &&
Loading…
} <div>
<h2>Rain Data</h2>
{rainError ? (
<p>Error: {rainError}</p>
) : (
<pre>{JSON.stringify(rainData, null, 2)}</pre>
)}
<h2>Temperature Data</h2>
{tempError ? (
<p>Error: {tempError}</p>
) : (
<pre>{JSON.stringify(temperatureData, null, 2)}</pre>
)}
{displayMap.size > 0 && (
<div>
<h2>Combined Data</h2>
<ul>
{Array.from(displayMap.entries()).map(([city, data]) => (
<li key={city}>
<strong>{city}</strong>: Rain - {data.rain}mm, Temperature - {data.temperature}°F
</li>
))}
</ul>
</div>
)}
</div>
</div>
);
}
export default App;
I failed, but later tried a solution with chatgpt