Skip to content

Commit 67780d8

Browse files
mpiannucciclaude
andcommitted
Fix OpenDAP browser data fetching and dimension parsing
Major fixes to the React OpenDAP browser: - Add custom DDS parser to extract real dimensions (workaround for broken getVariablesInfo) - Fix data fetching with proper constraint building and timeouts - Always use constraints for multi-dimensional variables to prevent hanging - Add background coordinate value fetching with proper error handling - Enhanced UI feedback showing exact constraints used for data fetching - Add debug script for isolating data fetching issues The browser now correctly shows variable dimensions (e.g., latitude[721] vs scalar) and successfully fetches data using constraints like "latitude[100],longitude[200]". 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 7fc3fc4 commit 67780d8

File tree

3 files changed

+298
-40
lines changed

3 files changed

+298
-40
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* debug-simple.js - Simple debug script to test basic OpenDAP operations
5+
*
6+
* This script tests the basic functionality of @mattnucc/readap by:
7+
* 1. Loading a dataset
8+
* 2. Fetching latitude coordinate data
9+
* 3. Printing the results
10+
*/
11+
12+
import init, { ImmutableDataset, SimpleConstraintBuilder } from '@mattnucc/readap';
13+
14+
const URL = 'https://compute.earthmover.io/v1/services/dap2/earthmover-demos/gfs/main/solar/opendap';
15+
16+
async function main() {
17+
console.log('=== Simple OpenDAP Debug Script ===');
18+
console.log('URL:', URL);
19+
console.log('');
20+
21+
try {
22+
// Initialize WASM
23+
console.log('1. Initializing WASM...');
24+
await init();
25+
console.log('✓ WASM initialized');
26+
console.log('');
27+
28+
// Load dataset
29+
console.log('2. Loading dataset...');
30+
const dataset = await ImmutableDataset.fromURL(URL);
31+
console.log('✓ Dataset loaded');
32+
console.log('');
33+
34+
// Get variable names
35+
console.log('3. Getting variable names...');
36+
const varNames = dataset.getVariableNames();
37+
console.log('✓ Variable names:', varNames);
38+
console.log('');
39+
40+
// Get variables info
41+
console.log('4. Getting variables info...');
42+
const variablesInfoJson = dataset.getVariablesInfo();
43+
const variablesInfo = JSON.parse(variablesInfoJson);
44+
console.log('✓ Variables info loaded');
45+
46+
// Print all variables info to see the structure
47+
console.log('All variables:');
48+
for (const [name, info] of Object.entries(variablesInfo)) {
49+
console.log(` ${name}:`);
50+
console.log(` Type: ${info.data_type}`);
51+
console.log(` Dimensions: ${JSON.stringify(info.dimensions)}`);
52+
console.log(` Attributes: ${Object.keys(info.attributes || {}).length} attributes`);
53+
}
54+
console.log('');
55+
56+
// Check DDS directly
57+
console.log('DDS URL:', dataset.ddsUrl());
58+
console.log('DAS URL:', dataset.dasUrl());
59+
console.log('');
60+
61+
// Test data fetching with timeout
62+
console.log('5. Testing data fetching...');
63+
64+
try {
65+
// Approach 1: Fetch with timeout
66+
console.log('Approach 1: Fetching latitude with 10s timeout...');
67+
const fetchPromise = dataset.getVariable('latitude');
68+
const timeoutPromise = new Promise((_, reject) =>
69+
setTimeout(() => reject(new Error('Timeout after 10 seconds')), 10000)
70+
);
71+
72+
const latData1 = await Promise.race([fetchPromise, timeoutPromise]);
73+
console.log('✓ Fetched latitude data (all):');
74+
console.log(' Data type:', typeof latData1.data);
75+
console.log(' Data length:', latData1.data.length);
76+
console.log(' First 5 values:', Array.from(latData1.data.slice(0, 5)));
77+
console.log(' Last 5 values:', Array.from(latData1.data.slice(-5)));
78+
console.log('');
79+
} catch (err) {
80+
console.error('✗ Approach 1 failed:', err.message);
81+
}
82+
83+
try {
84+
// Approach 2: Fetch with simple constraint
85+
console.log('Approach 2: Fetching latitude with constraint latitude[0:4]...');
86+
const latData2 = await dataset.getVariable('latitude', 'latitude[0:4]');
87+
console.log('✓ Fetched latitude data (constrained):');
88+
console.log(' Data type:', typeof latData2.data);
89+
console.log(' Data length:', latData2.data.length);
90+
console.log(' Values:', Array.from(latData2.data));
91+
console.log('');
92+
} catch (err) {
93+
console.error('✗ Approach 2 failed:', err.message);
94+
}
95+
96+
try {
97+
// Approach 3: Fetch with SimpleConstraintBuilder
98+
console.log('Approach 3: Using SimpleConstraintBuilder...');
99+
let builder = new SimpleConstraintBuilder();
100+
builder = builder.addRange('latitude', 0, 4);
101+
const constraint = builder.build();
102+
console.log(' Built constraint:', constraint);
103+
104+
const latData3 = await dataset.getVariable('latitude', constraint);
105+
console.log('✓ Fetched latitude data (builder):');
106+
console.log(' Data type:', typeof latData3.data);
107+
console.log(' Data length:', latData3.data.length);
108+
console.log(' Values:', Array.from(latData3.data));
109+
console.log('');
110+
} catch (err) {
111+
console.error('✗ Approach 3 failed:', err.message);
112+
}
113+
114+
try {
115+
// Approach 4: Single index
116+
console.log('Approach 4: Single index with SimpleConstraintBuilder...');
117+
let builder = new SimpleConstraintBuilder();
118+
builder = builder.addSingle('latitude', 0);
119+
const constraint = builder.build();
120+
console.log(' Built constraint:', constraint);
121+
122+
const latData4 = await dataset.getVariable('latitude', constraint);
123+
console.log('✓ Fetched latitude data (single):');
124+
console.log(' Data type:', typeof latData4.data);
125+
console.log(' Data length:', latData4.data.length);
126+
console.log(' Values:', Array.from(latData4.data));
127+
console.log('');
128+
} catch (err) {
129+
console.error('✗ Approach 4 failed:', err.message);
130+
}
131+
132+
console.log('=== Debug Complete ===');
133+
134+
} catch (error) {
135+
console.error('Fatal error:', error.message);
136+
console.error('Stack:', error.stack);
137+
process.exit(1);
138+
}
139+
}
140+
141+
main().catch(err => {
142+
console.error('Unhandled error:', err);
143+
process.exit(1);
144+
});

readap-wasm/examples/opendap-browser/src/components/DataVisualization.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,10 @@ function DataVisualization({ data, metadata }) {
160160
<div className="data-info">
161161
<h3>{data.variable}</h3>
162162
<p>Data type: {metadata.variables[data.variable]?.data_type}</p>
163-
<p>Total values: {data.data.length}</p>
163+
<p>Values fetched: {data.data.length}</p>
164+
{data.constraint && (
165+
<p>Constraint used: <code>{data.constraint}</code></p>
166+
)}
164167

165168
{data.attributes && Object.keys(data.attributes).length > 0 && (
166169
<div className="attributes">

0 commit comments

Comments
 (0)