Bird
Raised Fist0
Fluttermobile~20 mins

Why local storage enables offline data in Flutter - Build It to Prove It

Choose your learning style10 modes available
Build: Offline Notes
A simple notes app that saves notes locally so you can access them even without internet.
Target UI
-------------------------
| Offline Notes          |
|-----------------------|
| [Type your note here] |
|                       |
| [Save Note]           |
|-----------------------|
| Saved Notes:          |
| - Note 1              |
| - Note 2              |
|                       |
-------------------------
A TextField to enter a note
A Save button to save the note locally
A list below showing all saved notes
Notes must persist after app restart (use local storage)
App works without internet connection
Starter Code
Flutter
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: OfflineNotesScreen(),
    );
  }
}

class OfflineNotesScreen extends StatefulWidget {
  const OfflineNotesScreen({super.key});

  @override
  State<OfflineNotesScreen> createState() => _OfflineNotesScreenState();
}

class _OfflineNotesScreenState extends State<OfflineNotesScreen> {
  final TextEditingController _controller = TextEditingController();
  List<String> _notes = [];

  @override
  void initState() {
    super.initState();
    // TODO: Load saved notes from local storage here
  }

  void _saveNote() {
    final text = _controller.text.trim();
    if (text.isEmpty) return;
    setState(() {
      _notes.add(text);
      _controller.clear();
      // TODO: Save updated notes list to local storage here
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Offline Notes')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(
                labelText: 'Type your note here',
              ),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: _saveNote,
              child: const Text('Save Note'),
            ),
            const SizedBox(height: 20),
            const Text('Saved Notes:'),
            Expanded(
              child: ListView.builder(
                itemCount: _notes.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_notes[index]),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: OfflineNotesScreen(),
    );
  }
}

class OfflineNotesScreen extends StatefulWidget {
  const OfflineNotesScreen({super.key});

  @override
  State<OfflineNotesScreen> createState() => _OfflineNotesScreenState();
}

class _OfflineNotesScreenState extends State<OfflineNotesScreen> {
  final TextEditingController _controller = TextEditingController();
  List<String> _notes = [];

  @override
  void initState() {
    super.initState();
    _loadNotes();
  }

  Future<void> _loadNotes() async {
    final prefs = await SharedPreferences.getInstance();
    final savedNotes = prefs.getStringList('notes') ?? [];
    setState(() {
      _notes = savedNotes;
    });
  }

  Future<void> _saveNotes() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setStringList('notes', _notes);
  }

  void _saveNote() {
    final text = _controller.text.trim();
    if (text.isEmpty) return;
    setState(() {
      _notes.add(text);
      _controller.clear();
    });
    _saveNotes();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Offline Notes')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _controller,
              decoration: const InputDecoration(
                labelText: 'Type your note here',
              ),
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: _saveNote,
              child: const Text('Save Note'),
            ),
            const SizedBox(height: 20),
            const Text('Saved Notes:'),
            Expanded(
              child: ListView.builder(
                itemCount: _notes.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(_notes[index]),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

This app uses the shared_preferences package to save notes locally on the device. When the app starts, it loads saved notes from local storage in initState. When the user adds a note, it updates the list and saves it back to local storage.

This means the notes stay saved even if the app is closed or the device is offline. Local storage allows the app to work without internet because data is stored right on the device.

Final Result
Completed Screen
-------------------------
| Offline Notes          |
|-----------------------|
| [Type your note here] |
|                       |
| [Save Note]           |
|-----------------------|
| Saved Notes:          |
| - Buy groceries       |
| - Call mom            |
|                       |
-------------------------
User types a note in the TextField
User taps 'Save Note' button to add note to list
Notes appear below in the list
Notes remain after app restart or offline use
Stretch Goal
Add a button to clear all saved notes from local storage
💡 Hint
Use shared_preferences to remove the saved notes list and update the UI

Practice

(1/5)
1. Why does local storage enable offline data in mobile apps?
easy
A. Because it requires a constant internet connection to fetch data.
B. Because it only works when the app is online.
C. Because it deletes data when the app is closed.
D. Because it saves data directly on the device, allowing access without internet.

Solution

  1. Step 1: Understand local storage purpose

    Local storage keeps data saved on the device itself, not on the internet.
  2. Step 2: Connect local storage to offline use

    Since data is on the device, the app can access it anytime, even without internet.
  3. Final Answer:

    Because it saves data directly on the device, allowing access without internet. -> Option D
  4. Quick Check:

    Local storage = offline access [OK]
Hint: Local storage means data stays on device, no internet needed [OK]
Common Mistakes:
  • Thinking local storage needs internet
  • Confusing local storage with cloud storage
  • Assuming data is deleted when offline
2. Which Flutter code snippet correctly saves a string value using SharedPreferences for offline use?
easy
A. final prefs = await SharedPreferences.getInstance(); await prefs.setString('key', 'value');
B. SharedPreferences.setString('key', 'value');
C. prefs.saveString('key', 'value');
D. SharedPreferences.getString('key', 'value');

Solution

  1. Step 1: Identify correct SharedPreferences usage

    SharedPreferences requires getting an instance asynchronously before saving data.
  2. Step 2: Check method correctness

    The method to save a string is setString with key and value parameters.
  3. Final Answer:

    final prefs = await SharedPreferences.getInstance(); await prefs.setString('key', 'value'); -> Option A
  4. Quick Check:

    SharedPreferences usage = final prefs = await SharedPreferences.getInstance(); await prefs.setString('key', 'value'); [OK]
Hint: Always await SharedPreferences.getInstance() before saving [OK]
Common Mistakes:
  • Calling setString without getting instance
  • Using wrong method names like saveString
  • Trying to pass two arguments to getString
3. What will this Flutter code print if the device is offline but data was saved locally?
final prefs = await SharedPreferences.getInstance();
String? name = prefs.getString('username');
print(name ?? 'No user');
medium
A. The saved username string
B. null
C. No user
D. Error: No internet connection

Solution

  1. Step 1: Understand SharedPreferences data retrieval

    SharedPreferences reads data stored locally on the device, independent of internet.
  2. Step 2: Analyze code behavior when offline

    Since data was saved before, prefs.getString('username') returns the saved string, not null.
  3. Final Answer:

    The saved username string -> Option A
  4. Quick Check:

    Local data access = saved string [OK]
Hint: Local storage returns saved data even offline [OK]
Common Mistakes:
  • Assuming getString returns null if offline
  • Expecting an error without internet
  • Confusing null and 'No user' output
4. Identify the error in this Flutter code that tries to save data locally:
SharedPreferences prefs;
prefs.setString('token', 'abc123');
medium
A. The key 'token' cannot be a string.
B. SharedPreferences instance is not initialized before use.
C. setString method does not exist in SharedPreferences.
D. You cannot save strings in SharedPreferences.

Solution

  1. Step 1: Check SharedPreferences instance initialization

    The code declares prefs but does not assign an instance using getInstance().
  2. Step 2: Understand consequences of missing initialization

    Without initialization, calling setString causes a runtime error because prefs is null.
  3. Final Answer:

    SharedPreferences instance is not initialized before use. -> Option B
  4. Quick Check:

    Initialize prefs before use [OK]
Hint: Always await SharedPreferences.getInstance() before using prefs [OK]
Common Mistakes:
  • Forgetting to initialize prefs
  • Thinking setString is invalid
  • Believing keys cannot be strings
5. You want your Flutter app to show user data instantly even when offline. Which approach best uses local storage to achieve this?
hard
A. Clear all local data when the app closes to save space.
B. Only fetch user data from the internet every time the app opens.
C. Save user data in SharedPreferences after first online fetch, then read from it when offline.
D. Use local storage only for caching images, not user data.

Solution

  1. Step 1: Understand offline data availability

    To show data offline, it must be saved locally after fetching online once.
  2. Step 2: Choose best local storage use

    SharedPreferences is suitable for small user data; saving after first fetch allows instant offline access.
  3. Final Answer:

    Save user data in SharedPreferences after first online fetch, then read from it when offline. -> Option C
  4. Quick Check:

    Save after fetch = offline access [OK]
Hint: Save data locally after online fetch for offline use [OK]
Common Mistakes:
  • Relying only on internet every time
  • Clearing local data unnecessarily
  • Ignoring local storage for user data
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard