Snowflake Technical Phone Screen FE

:clipboard: Problem Statement

You are given two asynchronous API functions:

  • getTemperatureData(day) — returns a Promise resolving to an object mapping cities to temperature data.
  • getRainData(day) — returns a Promise 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