Skip to content

Survey Results Recipe ​

Patterns for handling and processing survey results from Sibilance.

Overview ​

This recipe covers common patterns for handling survey results, including submission, storage, and processing.

Basic Result Handling ​

Access Results ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: (yaml) => {
    // yaml is an array of collected information
    console.log('Results:', yaml);
    
    // Example structure:
    // [
    //   { field: 'name', value: 'John Doe', sourceStep: 'introduction', timestamp: 1234567890 },
    //   { field: 'email', value: 'john@example.com', sourceStep: 'contact', timestamp: 1234567891 },
    //   { field: 'project_type', value: 'residential', sourceStep: 'project_details', timestamp: 1234567892 }
    // ]
  }
});

Get Results Programmatically ​

typescript
// Get results at any time
const surveyState = client.getSurveyState();
const results = surveyState.collectedInfo;

// Or get YAML format
const yaml = client.getYAML();

Result Submission ​

Submit to API ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: async (yaml) => {
    try {
      const response = await fetch('/api/survey-results', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          surveyId: 'your-survey-id',
          results: yaml,
          timestamp: new Date().toISOString(),
          userAgent: navigator.userAgent
        })
      });
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      const data = await response.json();
      console.log('Results submitted:', data);
    } catch (error) {
      console.error('Failed to submit:', error);
      // Retry or show error
    }
  }
});

Submit with Retry Logic ​

typescript
async function submitWithRetry(yaml: any[], maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('/api/survey-results', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ results: yaml })
      });
      
      if (response.ok) {
        return await response.json();
      }
      
      throw new Error(`HTTP ${response.status}`);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: async (yaml) => {
    try {
      await submitWithRetry(yaml);
      console.log('Results submitted successfully');
    } catch (error) {
      console.error('Failed after retries:', error);
    }
  }
});

Result Processing ​

Transform Results ​

typescript
function processResults(yaml: any[]) {
  // Transform to your data structure
  const processed = yaml.reduce((acc, item) => {
    acc[item.field] = {
      value: item.value,
      step: item.sourceStep,
      timestamp: new Date(item.timestamp)
    };
    return acc;
  }, {} as Record<string, any>);
  
  return processed;
}

const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: (yaml) => {
    const processed = processResults(yaml);
    console.log('Processed results:', processed);
  }
});

Validate Results ​

typescript
function validateResults(yaml: any[]): { valid: boolean; errors: string[] } {
  const errors: string[] = [];
  
  // Check required fields
  const requiredFields = ['name', 'email'];
  for (const field of requiredFields) {
    if (!yaml.find(item => item.field === field)) {
      errors.push(`Missing required field: ${field}`);
    }
  }
  
  // Validate email format
  const emailItem = yaml.find(item => item.field === 'email');
  if (emailItem && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailItem.value)) {
    errors.push('Invalid email format');
  }
  
  return {
    valid: errors.length === 0,
    errors
  };
}

const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: (yaml) => {
    const validation = validateResults(yaml);
    
    if (validation.valid) {
      submitResults(yaml);
    } else {
      console.error('Validation errors:', validation.errors);
      // Show errors to user
    }
  }
});

Result Storage ​

Local Storage ​

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: (yaml) => {
    // Store locally as backup
    const stored = {
      results: yaml,
      timestamp: new Date().toISOString(),
      surveyKey: 'sibilance_your_key_here'
    };
    
    const existing = JSON.parse(localStorage.getItem('survey-results') || '[]');
    existing.push(stored);
    localStorage.setItem('survey-results', JSON.stringify(existing));
  }
});

IndexedDB ​

typescript
async function storeInIndexedDB(yaml: any[]) {
  const db = await openDB('survey-results', 1, {
    upgrade(db) {
      db.createObjectStore('results', { keyPath: 'id', autoIncrement: true });
    }
  });
  
  await db.add('results', {
    results: yaml,
    timestamp: new Date().toISOString()
  });
}

const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: async (yaml) => {
    await storeInIndexedDB(yaml);
  }
});

Result Display ​

Display Results in UI ​

tsx
function ResultsDisplay() {
  const [results, setResults] = useState<any[]>([]);
  
  const { surveyState } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  }, {
    onComplete: (yaml) => {
      setResults(yaml);
    }
  });

  return (
    <div className="results">
      <h3>Survey Results</h3>
      {results.map((item, i) => (
        <div key={i} className="result-item">
          <strong>{item.field}:</strong> {item.value}
          {item.sourceStep && (
            <small> (from {item.sourceStep})</small>
          )}
        </div>
      ))}
    </div>
  );
}

Export Results ​

typescript
function exportResults(yaml: any[], format: 'json' | 'csv' = 'json') {
  if (format === 'json') {
    const blob = new Blob([JSON.stringify(yaml, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `survey-results-${Date.now()}.json`;
    a.click();
  } else if (format === 'csv') {
    const headers = ['Field', 'Value', 'Step', 'Timestamp'];
    const rows = yaml.map(item => [
      item.field,
      item.value,
      item.sourceStep || '',
      new Date(item.timestamp).toISOString()
    ]);
    
    const csv = [headers, ...rows]
      .map(row => row.map(cell => `"${cell}"`).join(','))
      .join('\n');
    
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `survey-results-${Date.now()}.csv`;
    a.click();
  }
}

const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here'
}, {
  onComplete: (yaml) => {
    exportResults(yaml, 'json');
  }
});