This guide helps you migrate from previous versions to v0.3.0, which includes significant improvements to DOM readiness handling, error management, and new callback APIs.
Before (v0.2.x):
final keyEditor = GlobalKey<FlutterSummernoteState>();
// These methods returned void
keyEditor.currentState?.setText("Hello World");
keyEditor.currentState?.setFocus();
keyEditor.currentState?.setEmpty();
keyEditor.currentState?.setFullContainer();
keyEditor.currentState?.setHint("Type here...");After (v0.3.0):
final keyEditor = GlobalKey<FlutterSummernoteState>();
// These methods now return Future<bool>
final success = await keyEditor.currentState?.setText("Hello World");
if (success == true) {
log("Text set successfully");
} else {
log("Failed to set text");
}
await keyEditor.currentState?.setFocus();
await keyEditor.currentState?.setEmpty();
await keyEditor.currentState?.setFullContainer();
await keyEditor.currentState?.setHint("Type here...");Before (v0.2.x):
- Editor was immediately available (but might fail silently)
After (v0.3.0):
- Editor shows a modern loading indicator until fully initialized
- Operations are blocked until editor is ready
- Clear visual feedback for initialization state
Add new callback functions to handle editor lifecycle events:
FlutterSummernote(
key: keyEditor,
offlineSupport: true,
// NEW: Called when editor is fully ready
onReady: () {
log('Editor is ready for use!');
// Safe to call editor methods now
},
// NEW: Called when errors occur
onError: (String error) {
log('Editor error: $error');
// Handle errors appropriately
},
// NEW: Called when editor gains focus
onFocus: () {
log('Editor focused');
},
// NEW: Called when editor loses focus
onBlur: () {
log('Editor blurred');
},
// Existing callback (unchanged)
returnContent: (String content) {
log('Content changed: $content');
},
)Check if the editor is ready before performing operations:
final keyEditor = GlobalKey<FlutterSummernoteState>();
// NEW: Check if editor is ready
if (keyEditor.currentState?.isReady == true) {
await keyEditor.currentState?.setText("Safe to set text");
} else {
log("Editor not ready yet");
}Access error information from the editor state:
final keyEditor = GlobalKey<FlutterSummernoteState>();
// NEW: Get last error message
final error = keyEditor.currentState?.errorMessage;
if (error != null) {
log("Last error: $error");
}- Add
awaitto all editor method calls - Handle the
Future<bool>return values - Add error checking where needed
- Add
onReadycallback to know when editor is initialized - Add
onErrorcallback for error handling - Optionally add
onFocusandonBlurfor UI feedback
Replace silent failures with proper error handling:
Before:
// Silent failure - no way to know if it worked
keyEditor.currentState?.setText("Hello");After:
// Proper error handling
try {
final success = await keyEditor.currentState?.setText("Hello");
if (success != true) {
// Handle failure
showErrorDialog("Failed to set text");
}
} catch (e) {
// Handle exception
showErrorDialog("Error: $e");
}The editor now shows a loading indicator automatically, but you can customize your UI based on the ready state:
class MyEditorWidget extends StatefulWidget {
@override
_MyEditorWidgetState createState() => _MyEditorWidgetState();
}
class _MyEditorWidgetState extends State<MyEditorWidget> {
final keyEditor = GlobalKey<FlutterSummernoteState>();
bool editorReady = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
// Your custom UI can react to editor state
if (!editorReady)
Text("Please wait, editor is loading..."),
Expanded(
child: FlutterSummernote(
key: keyEditor,
offlineSupport: true,
onReady: () {
setState(() {
editorReady = true;
});
},
onError: (error) {
setState(() {
editorReady = false;
});
// Show error to user
},
),
),
// Buttons are disabled until editor is ready
ElevatedButton(
onPressed: editorReady ? () async {
await keyEditor.currentState?.setText("Hello");
} : null,
child: Text("Set Text"),
),
],
);
}
}Problem:
// This won't work anymore
keyEditor.currentState?.setText("Hello");
final text = keyEditor.currentState?.getText(); // May be emptySolution:
// Wait for operations to complete
await keyEditor.currentState?.setText("Hello");
final text = await keyEditor.currentState?.getText();Problem:
// Silent failures
keyEditor.currentState?.setText("Hello");Solution:
// Proper error handling
final success = await keyEditor.currentState?.setText("Hello");
if (success != true) {
// Handle the error
log("Failed to set text");
}Problem:
// Called immediately after widget creation
keyEditor.currentState?.setText("Hello"); // May failSolution:
// Wait for onReady callback
FlutterSummernote(
onReady: () async {
// Now safe to call methods
await keyEditor.currentState?.setText("Hello");
},
)- Reliability: No more silent failures due to DOM timing issues
- Better UX: Clear loading states and error feedback
- Debugging: Detailed error information and logging
- Future-proof: Robust foundation for future features
Use the new stress test example to verify your implementation:
import 'package:flutter_summernote/example/stress_test_example.dart';
// Run stress tests to ensure reliability
Navigator.push(
context,
MaterialPageRoute(builder: (context) => StressTestExample()),
);- Check the new error handling example for implementation patterns
- Use the stress test to verify your implementation
- Enable debug mode to see detailed error information
- Check the console for initialization and error logs
For more examples, see:
example/lib/error_handling_example.dartexample/lib/stress_test_example.dart