Handling User Data

Process and use the data captured from Story interactions.

Overview

Stories can capture user input through interactive elements like select lists, card selects, bubble pickers, and toggles. This guide explains how to access and use that data.

Response Structure

When a Story completes, you receive a StoryResponse:

interface StoryResponse {
  completed: boolean                    // true when Story finishes (includes Close on final screen)
  contentId: string                     // Unique story identifier
  selections: Record<string, string[]>  // From selection elements
  toggles: Record<string, boolean | Record<string, boolean>>  // From toggles
}

Accessing Data

In showStory Callback

Snoopr.showStory({
  onFinish: (response) => {
    if (response.completed) {
      const interests = response.selections['user_interests']  // ['fitness', 'nutrition']
      const plan = response.selections['selected_plan']        // ['premium']
      const notifications = response.toggles['notifications']  // true

      // Use the data
      updateUserProfile({ interests, plan, notifications })
    }
  }
})

In Provider Callback

For centralized handling across all Stories:

<SnooprProvider
  appId="app-xxx"
  apiKey="sk_live_xxx"
  onFinish={(responses) => {
    // responses has same structure as StoryResponse
    // (minus completed/contentId)
    saveToAnalytics(responses.selections)
  }}
>

Both callbacks fire when a Story completes.

Element Names

The keys in selections and toggles correspond to the Name field configured in the Snoopr dashboard for each element.

Example: If you create a Select List and set its Name to user_interests, the captured values appear at response.selections['user_interests'].

Selection Elements

These elements populate response.selections:

Element TypeCaptured Value
Select ListArray of selected option values
Card SelectArray of selected card values
Bubble PickerArray of selected bubble values
Checkbox ListArray of checked option values
Image Select GridArray of selected image values

All selection elements return arrays, even for single-select variants.

// Single select - array with one item
response.selections['plan']  // ['premium']

// Multi-select - array with multiple items
response.selections['interests']  // ['fitness', 'nutrition', 'sleep']

Toggle Elements

These elements populate response.toggles:

Element TypeCaptured Value
Toggleboolean
Toggle ListRecord<string, boolean> (keyed by item name)
// Single toggle
response.toggles['notifications']  // true

// Toggle list
response.toggles['settings']  // { 'dark_mode': true, 'auto_play': false }

Data Privacy

Captured responses never leave the device for Snoopr's servers. The SDK passes data directly to your callbacks. You control where it goes.

Common Patterns

Save to Backend

Snoopr.showStory({
  onFinish: async (response) => {
    await fetch('/api/user/preferences', {
      method: 'POST',
      body: JSON.stringify({
        userId: currentUser.id,
        preferences: response.selections,
        settings: response.toggles
      })
    })
  }
})

Update Local State

Snoopr.showStory({
  onFinish: (response) => {
    // Update React state
    setUserPreferences(response.selections)

    // Update AsyncStorage
    AsyncStorage.setItem('preferences', JSON.stringify(response.selections))
  }
})

Conditional Navigation

Snoopr.showStory({
  onFinish: (response) => {
    const plan = response.selections['selected_plan']?.[0]

    if (plan === 'premium') {
      navigation.navigate('PremiumSetup')
    } else {
      navigation.navigate('Home')
    }
  }
})

Analytics Integration

Send captured data to your analytics provider.

Snoopr.showStory({
  onFinish: (response) => {
    // Send to your analytics provider
    analytics.track('onboarding_completed', {
      interests: response.selections['interests'],
      plan: response.selections['plan']?.[0],
      notificationsEnabled: response.toggles['notifications']
    })
  }
})