Writing a State Notifier

  • The issue is that StateNotifier only notifies listeners when you reassign the state property.
  • When you mutate the existing state object (which is what’s happening with state.add(), state.nextReady(), etc.), the StateNotifier doesn’t detect the change and doesn’t notify listeners.
  • The problem is on these lines:
Line 26: state.add(id, task, shouldRequeue: shouldRequeue); - mutates state
Line 31: return state.nextReady(); - mutates state
Line 36: return state.setCompleted(id); - mutates state
Line 41: state.setErrored(id); - mutates state
Line 46: state.clearErrors(); - mutates state
  • The UploadStateNotifier was mutating the state object directly without triggering listener notifications.
  • In the StateNotifier pattern, you need to reassign the state property to trigger notifications, even if you’re just assigning it to itself.

The Fix

  • I added state = state; after each mutation in the UploadStateNotifier:
addTask - After calling state.add()
nextReadyTask - After calling state.nextReady()
setCompleted - After calling state.setCompleted()
setErrored - After calling state.setErrored()
clearErrors - After calling state.clearErrors()

This pattern of reassigning state = state works because

  • StateNotifier uses a setter that compares the identity of the state object
  • Even though you’re mutating the internal collections (LRUFixedMap), the state object reference remains the same
  • By reassigning state = state, you explicitly tell StateNotifier that the state has changed, triggering all listeners

Key Takeaway

  • With StateNotifier (and similar state management patterns like ChangeNotifier), you need to explicitly trigger notifications.
  • Unlike some reactive frameworks that detect mutations automatically, StateNotifier relies on you to signal when the state has changed by reassigning the state property.