/** * js/api.js * Data layer for fetching measurement data (temperature & audio) from the backend API. * * @module api */ /** * Builds a query string from optional parameters. * @param {Object} [params={}] - Optional query parameters. * @returns {string} Query string starting with '?', or empty string if no params. */ function buildQueryString(params = {}) { const query = Object.entries(params) .filter(([_, v]) => v != null && v !== '') .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) .join('&'); return query ? `?${query}` : ''; } /** * Fetches measurement data from the /data API endpoint. * * @async * @param {Object} [filters] - Optional filters, e.g. { sensorType: 'temperature', timeRange: '24h' }. * @returns {Promise} Resolves with parsed JSON { temperature: [...], audio: [...] }. * @throws Will throw an error if the fetch response is not OK or JSON is invalid. */ export async function fetchData(filters = {}) { const queryString = buildQueryString(filters); const url = `/data${queryString}`; try { const response = await fetch(url, { method: 'GET', headers: { 'Accept': 'application/json' } }); if (!response.ok) { throw new Error(`Fetch error: ${response.status} ${response.statusText}`); } const data = await response.json(); // Defensive checks if (!data || typeof data !== 'object' || !Array.isArray(data.temperature) || !Array.isArray(data.audio)) { throw new Error('Invalid data format from API'); } return data; } catch (error) { console.error('Error fetching data:', error); throw error; } }