Getting Started

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

MongoDB Integration - Getting Started Guide

Last Updated: October 10, 2025
Version: 1.0.0
Difficulty: Beginner


Table of Contents

  1. Prerequisites
  2. Installation
  3. MongoDB Atlas Setup
  4. Basic Configuration
  5. Your First Sync
  6. Common Patterns
  7. Next Steps

Prerequisites

Before you begin, ensure you have:

If you haven't set up Flash Persistence yet, see the Flash Persistence Guide first.


Installation

The MongoDB integration is already included in @storage-system. No additional installation needed!

# storage-system is already in your workspace
# Just import from the sync module

MongoDB Atlas Setup

Step 1: Create a MongoDB Atlas Account

  1. Go to https://www.mongodb.com/cloud/atlas/register
  2. Sign up for a free account
  3. Verify your email

Step 2: Create a Cluster

  1. Click "Build a Database"
  2. Choose FREE (M0) tier
  3. Select your preferred cloud provider (AWS recommended)
  4. Choose a region close to your users (e.g., us-east-1)
  5. Name your cluster (e.g., MyAppCluster)
  6. Click "Create Cluster"

⏱️ Wait Time: Cluster creation takes ~5 minutes.

Step 3: Configure Database Access

  1. Go to Database Access in the left sidebar
  2. Click "Add New Database User"
  3. Choose "Password" authentication
  4. Create a username and secure password
  5. Grant "Read and write to any database" permission
  6. Click "Add User"

💡 Tip: Save your username and password securely!

Step 4: Configure Network Access

  1. Go to Network Access in the left sidebar
  2. Click "Add IP Address"
  3. For development, click "Allow Access from Anywhere" (0.0.0.0/0)
  4. For production, add specific IP addresses

⚠️ Security Note: In production, restrict to your server IPs only!

Step 5: Get Your Connection String

  1. Go to Database in the left sidebar
  2. Click "Connect" on your cluster
  3. Choose "Connect your application"
  4. Select Driver: Node.js and Version: 5.5 or later
  5. Copy the connection string

Your connection string looks like:

mongodb+srv://username:[email protected]/?retryWrites=true&w=majority

💡 Important: Replace <password> with your actual password!


Basic Configuration

Step 1: Create Environment Configuration

Create or update your environments/environment.ts:

export const environment = {
  production: false,
  mongodb: {
    connectionString: 'mongodb+srv://username:[email protected]/?retryWrites=true&w=majority',
    database: 'my-app-db'
  }
};

And for production (environments/environment.prod.ts):

export const environment = {
  production: true,
  mongodb: {
    connectionString: process.env['MONGODB_CONNECTION_STRING'] || '',
    database: 'my-app-prod-db'
  }
};

⚠️ Security: Never commit connection strings to git! Use environment variables in production.


Step 2: Provide MongoDB Sync in Your App

Update your app.config.ts (or main.ts if using bootstrapModule):

import { ApplicationConfig } from '@angular/core';
import { provideMongoDBSync } from '@storage-system/sync';
import { environment } from './environments/environment';

export const appConfig: ApplicationConfig = {
  providers: [
    // ... other providers
    
    provideMongoDBSync({
      connectionString: environment.mongodb.connectionString,
      database: environment.mongodb.database,
      
      // Optional: Auto-connect on app start
      autoConnect: true,
      
      // Optional: Default sync strategy
      defaultStrategy: 'offline-first',
      
      // Optional: Enable real-time for specific collections
      enableRealtime: ['messages', 'notifications']
    })
  ]
};

Step 3: Test the Connection

Create a simple component to test the connection:

import { Component, OnInit, signal } from '@angular/core';
import { inject } from '@angular/core';
import { MongoDBSyncAdapter } from '@storage-system/sync';

@Component({
  selector: 'app-connection-test',
  standalone: true,
  template: `
    <div class="connection-test">
      <h2>MongoDB Connection Test</h2>
      
      @if (isConnecting()) {
        <p>Connecting to MongoDB...</p>
      }
      
      @if (isConnected()) {
        <p class="success">✅ Connected to MongoDB!</p>
      }
      
      @if (error()) {
        <p class="error">❌ Connection failed: {{ error() }}</p>
      }
      
      <button (click)="testConnection()">Test Connection</button>
    </div>
  `,
  styles: [`
    .connection-test {
      padding: 2rem;
      
      .success {
        color: green;
      }
      
      .error {
        color: red;
      }
    }
  `]
})
export class ConnectionTestComponent implements OnInit {
  private adapter = inject(MongoDBSyncAdapter);
  
  isConnecting = signal(false);
  isConnected = signal(false);
  error = signal<string | null>(null);
  
  ngOnInit() {
    this.testConnection();
  }
  
  async testConnection() {
    this.isConnecting.set(true);
    this.error.set(null);
    
    try {
      await this.adapter.connect();
      this.isConnected.set(true);
      console.log('✅ MongoDB connected successfully!');
    } catch (err: any) {
      this.error.set(err.message);
      console.error('❌ MongoDB connection failed:', err);
    } finally {
      this.isConnecting.set(false);
    }
  }
}

Run your app and verify the connection!


Your First Sync

Now let's create a simple todo app with MongoDB sync!

Step 1: Define Your Data Model

// models/todo.model.ts
export interface Todo {
  id: string;
  title: string;
  completed: boolean;
  createdAt: number;
  priority: 'low' | 'medium' | 'high';
}

Step 2: Create a Component with Flash Persistence

// components/todo-list.component.ts
import { Component, computed } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { autoFlashState } from '@flash-persistence';
import type { Todo } from '../models/todo.model';

@Component({
  selector: 'app-todo-list',
  standalone: true,
  imports: [CommonModule, FormsModule],
  templateUrl: './todo-list.component.html',
  styleUrls: ['./todo-list.component.scss']
})
export class TodoListComponent {
  // Flash Persistence with MongoDB sync
  todos = autoFlashState<Todo[]>('todos', [], {
    database: 'my-app-db',
    collection: 'todos',
    priority: 'normal'
  });
  
  newTodoTitle = '';
  
  // Computed values
  incompleteTodos = computed(() => 
    this.todos().filter(t => !t.completed)
  );
  
  completedTodos = computed(() => 
    this.todos().filter(t => t.completed)
  );
  
  // Add todo
  addTodo() {
    if (!this.newTodoTitle.trim()) return;
    
    const newTodo: Todo = {
      id: Date.now().toString(),
      title: this.newTodoTitle,
      completed: false,
      createdAt: Date.now(),
      priority: 'medium'
    };
    
    this.todos.update(todos => [...todos, newTodo]);
    this.newTodoTitle = '';
  }
  
  // Toggle todo
  toggleTodo(id: string) {
    this.todos.update(todos =>
      todos.map(t => t.id === id ? { ...t, completed: !t.completed } : t)
    );
  }
  
  // Delete todo
  deleteTodo(id: string) {
    this.todos.update(todos => todos.filter(t => t.id !== id));
  }
}

Step 3: Create the Template

<!-- todo-list.component.html -->
<div class="todo-list">
  <h2>My Todos</h2>
  
  <!-- Add Todo Form -->
  <div class="add-todo">
    <input
      type="text"
      [(ngModel)]="newTodoTitle"
      (keyup.enter)="addTodo()"
      placeholder="What needs to be done?"
    />
    <button (click)="addTodo()">Add</button>
  </div>
  
  <!-- Incomplete Todos -->
  <div class="todo-section">
    <h3>Active ({{ incompleteTodos().length }})</h3>
    @for (todo of incompleteTodos(); track todo.id) {
      <div class="todo-item">
        <input
          type="checkbox"
          [checked]="todo.completed"
          (change)="toggleTodo(todo.id)"
        />
        <span>{{ todo.title }}</span>
        <button (click)="deleteTodo(todo.id)">Delete</button>
      </div>
    }
  </div>
  
  <!-- Completed Todos -->
  @if (completedTodos().length > 0) {
    <div class="todo-section">
      <h3>Completed ({{ completedTodos().length }})</h3>
      @for (todo of completedTodos(); track todo.id) {
        <div class="todo-item completed">
          <input
            type="checkbox"
            [checked]="todo.completed"
            (change)="toggleTodo(todo.id)"
          />
          <span>{{ todo.title }}</span>
          <button (click)="deleteTodo(todo.id)">Delete</button>
        </div>
      }
    </div>
  }
</div>

Step 4: Add Some Styles

// todo-list.component.scss
.todo-list {
  max-width: 600px;
  margin: 2rem auto;
  padding: 2rem;
  
  .add-todo {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 2rem;
    
    input {
      flex: 1;
      padding: 0.75rem;
      font-size: 1rem;
      border: 1px solid #ddd;
      border-radius: 4px;
    }
    
    button {
      padding: 0.75rem 1.5rem;
      background: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      
      &:hover {
        background: #0056b3;
      }
    }
  }
  
  .todo-section {
    margin-bottom: 2rem;
    
    h3 {
      margin-bottom: 1rem;
      color: #666;
    }
    
    .todo-item {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      padding: 0.75rem;
      background: white;
      border: 1px solid #e0e0e0;
      border-radius: 4px;
      margin-bottom: 0.5rem;
      
      &.completed {
        opacity: 0.6;
        
        span {
          text-decoration: line-through;
        }
      }
      
      input[type="checkbox"] {
        width: 20px;
        height: 20px;
        cursor: pointer;
      }
      
      span {
        flex: 1;
      }
      
      button {
        padding: 0.5rem 1rem;
        background: #dc3545;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        
        &:hover {
          background: #c82333;
        }
      }
    }
  }
}

Step 5: Test Your App!

  1. Run your app: nx serve your-app
  2. Add some todos - Notice they're instant! (0.3ms)
  3. Refresh the page - Todos are still there! (Flash Persistence)
  4. Check MongoDB Atlas - Your todos are syncing to the cloud!

What's Happening:


Common Patterns

Pattern 1: Different Priorities

// Critical data - syncs immediately
const paymentInfo = autoFlashState('payment', null, {
  database: 'my-app-db',
  collection: 'payments',
  priority: 'critical'
});

// Normal data - syncs in background
const userPreferences = autoFlashState('prefs', {}, {
  database: 'my-app-db',
  collection: 'preferences',
  priority: 'normal'
});

// Low priority - batches efficiently
const analytics = autoFlashState('analytics', [], {
  database: 'my-app-db',
  collection: 'analytics',
  priority: 'low'
});

Pattern 2: Real-Time Features

// Enable real-time for a component
import { inject, OnInit, OnDestroy } from '@angular/core';
import { MongoDBRealtimeService } from '@storage-system/sync';

export class MessagesComponent implements OnInit, OnDestroy {
  private realtimeService = inject(MongoDBRealtimeService);
  
  messages = autoFlashState<Message[]>('messages', [], {
    database: 'my-app-db',
    collection: 'messages'
  });
  
  ngOnInit() {
    // Enable real-time updates for messages
    this.realtimeService.enable('messages', {
      syncToLocal: true,
      filter: {
        operationType: ['insert', 'update']
      }
    });
  }
  
  ngOnDestroy() {
    // Clean up
    this.realtimeService.disable('messages');
  }
}

Pattern 3: Offline-First with Sync Status

import { inject } from '@angular/core';
import { IntelligentSyncEngine } from '@storage-system/sync';

export class MyComponent {
  private syncEngine = inject(IntelligentSyncEngine);
  
  todos = autoFlashState<Todo[]>('todos', []);
  
  // Check if a todo is synced
  isSynced(todoId: string): boolean {
    const status = this.syncEngine.getStatus('todos', todoId);
    return status === 'synced';
  }
  
  // Get sync statistics
  getSyncStats() {
    return this.syncEngine.getStatistics();
  }
  
  // Manually trigger sync
  async syncNow() {
    await this.syncEngine.processQueue();
  }
}

Pattern 4: Per-Collection Strategies

import { inject } from '@angular/core';
import { SyncConfigService } from '@storage-system/sync';

export class MyComponent {
  private configService = inject(SyncConfigService);
  
  ngOnInit() {
    // Configure different strategies per collection
    this.configService.setStrategy('cart', 'offline-first');
    this.configService.setStrategy('inventory', 'online-first');
    this.configService.setStrategy('messages', 'realtime');
  }
}

Pattern 5: Using Presets

import { inject } from '@angular/core';
import { SyncConfigService } from '@storage-system/sync';

export class MyComponent {
  private configService = inject(SyncConfigService);
  
  ngOnInit() {
    // Apply e-commerce preset
    this.configService.applyPreset('ecommerce');
    
    // Or messaging preset
    // this.configService.applyPreset('messaging');
    
    // Or custom preset
    this.configService.applyPreset('custom', {
      users: 'offline-first',
      posts: 'offline-first',
      comments: 'realtime',
      likes: 'low-priority'
    });
  }
}

Next Steps

Congratulations! You now have MongoDB sync working! 🎉

Continue Learning

  1. Configuration Reference - Explore all configuration options
  2. Advanced Topics - Custom strategies, performance tuning
  3. API Reference - Complete API documentation
  4. Troubleshooting - Common issues and solutions

Explore the Demos

Visit the live demos in your app:

Best Practices

✅ Use offline-first by default - Best user experience
✅ Set appropriate priorities - Critical data syncs immediately
✅ Enable real-time selectively - Only for data that needs it
✅ Monitor sync status - Show users sync state when relevant
✅ Test offline scenarios - Ensure app works without connection


Need Help?


Previous: ← Overview & Architecture
Next: Configuration Reference →