Skip to main content

UnitsContext Documentation

Overview

The UnitsContext is a global React context that manages metrics and units information throughout the application. It provides a centralized way to store, retrieve, and manage unit information for various metrics like chlorine, flow, pressure, etc.

Features

  • Global State Management: Provides units information across the entire application
  • API Integration: Fetches units from the Units/all API endpoint on first load
  • Local Storage Caching: Persists units data in localStorage for performance
  • Error Handling: Graceful error handling for API failures
  • Loading States: Provides loading indicators during API calls
  • Manual Updates: Allows manual updates and overrides of units

API Endpoint

The context fetches units from: API_BASE_URL + API_ENDPOINTS.GetAllUnits (which resolves to Units/all)

Usage

Basic Usage

import { useUnits } from '../contexts/UnitsContext';

const MyComponent = () => {
const { units, loading, error, getUnit, getAllUnits } = useUnits();

if (loading) return <div>Loading units...</div>;
if (error) return <div>Error: {error}</div>;

// Get a specific unit
const chlorineUnit = getUnit('chlorine'); // Returns "mg/L" or null

// Get all units
const allUnits = getAllUnits(); // Returns {chlorine: "mg/L", flow: "GPM", ...}

return (
<div>
<p>Chlorine unit: {chlorineUnit}</p>
<p>Total metrics: {Object.keys(units).length}</p>
</div>
);
};

Available Methods

State Properties

  • units: Object containing all units in format {metric: unit}
  • loading: Boolean indicating if units are being fetched
  • error: String containing error message if API call failed

Methods

  • getUnit(metric): Returns the unit for a specific metric, or null if not found
  • getAllUnits(): Returns a copy of all units object
  • updateUnits(newUnits): Manually update units with new values
  • refreshUnits(): Force refresh units from API
  • clearUnits(): Clear all units and remove from localStorage

Example: Displaying Units in a Table

import { useUnits } from '../contexts/UnitsContext';
import { Table, TableBody, TableCell, TableHead, TableRow, Paper } from '@mui/material';

const UnitsTable = () => {
const { units, loading } = useUnits();

if (loading) return <div>Loading...</div>;

return (
<Paper>
<Table>
<TableHead>
<TableRow>
<TableCell>Metric</TableCell>
<TableCell>Unit</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Object.entries(units).map(([metric, unit]) => (
<TableRow key={metric}>
<TableCell>{metric}</TableCell>
<TableCell>{unit}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
};

Example: Using Units in Charts

import { useUnits } from '../contexts/UnitsContext';

const ChartComponent = ({ data, metric }) => {
const { getUnit } = useUnits();
const unit = getUnit(metric);

return (
<div>
<h3>{metric} ({unit})</h3>
{/* Chart implementation */}
</div>
);
};

Data Format

The context expects the API to return data in one of these formats:

Array Format

[
{ "metric": "chlorine", "unit": "mg/L" },
{ "metric": "flow", "unit": "GPM" },
{ "metric": "pressure", "unit": "PSI" }
]

Object Format

{
"chlorine": "mg/L",
"flow": "GPM",
"pressure": "PSI"
}

Local Storage

Units are automatically cached in localStorage under the key 'unitsState'. The cache is:

  • Loaded on application startup
  • Updated when new data is fetched from API
  • Cleared when clearUnits() is called

Error Handling

The context handles various error scenarios:

  • Network errors during API calls
  • Invalid JSON responses
  • Missing or malformed data
  • localStorage access issues

Errors are logged to console and exposed via the error state property.

Integration

The UnitsProvider is already integrated into the main App component and is available globally throughout the application. No additional setup is required.

Testing

You can test the context by:

  1. Opening the browser console
  2. Checking localStorage for 'unitsState' key
  3. Using the UnitsDisplay component to visualize the data
  4. Calling refreshUnits() to force a new API fetch