search ESC

Searching…

No results for "".

Type at least 2 characters to search.

Docs
You are viewing an older version (0.0.3). Go to the latest.

Session & Flash Data

Introduction

The Session facade provides Laravel-style flash data that survives exactly one navigation hop. Use it to repopulate a form after a failed submit and a back navigation without wiring temporary state through controllers, the router, or global singletons.

The store has two buckets: the current bucket (readable by the view being built right now) and the next bucket (being collected by the currently-active handler). A call to Session.tick() promotes next into current, so flashed data is visible on exactly one frame.

Flashing Input

Flash a map of values before navigating away:

Session.flash({
  'name': 'John',
  'email': '[email protected]',
});
MagicRoute.back();

Flashing Errors

Flash per-field error messages:

Session.flashErrors({
  'email': ['The email has already been taken.'],
});

Reading Old Input

In the form view, repopulate via the old() helper:

WFormInput(
  initialValue: old('email') ?? '',
);

if (Session.hasError('email'))
  WText(Session.error('email')!, className: 'text-red-500');

Session.oldRaw(field) returns the original typed value (booleans, numbers, custom objects) instead of stringifying it.

Automatic Flash in MagicFormData

MagicFormData.validate() automatically flashes the current form data when validation fails, so you never need to wire it manually:

void _submit() {
  if (!form.validate()) return; // form data is auto-flashed on failure
  controller.register(form.data);
}

After a back navigation and a Session.tick(), old('email') returns the last-submitted value.

Advancing the Flash Bucket

Flash data survives exactly one navigation. Advance the bucket only when the router location actually changes. Do not wire Session.tick directly to the router delegate listener: the delegate can notify for more than real navigation (redirect re-evaluation, notifier rebuilds) and would expire flash data prematurely.

var lastLocation = MagicRouter.instance.currentLocation;

MagicRouter.instance.routerConfig.routerDelegate.addListener(() {
  final currentLocation = MagicRouter.instance.currentLocation;
  if (currentLocation == lastLocation) return;
  lastLocation = currentLocation;
  Session.tick();
});

Place this in a ServiceProvider.boot() after Magic.init() completes.

Testing

In tests, always reset the store in setUp():

setUp(() {
  MagicApp.reset();
  Magic.flush();
  Session.reset();
});

Swap the backing store with a custom SessionStore via Session.setStore(store) if you need isolated buckets per test group.