diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 6f89a08dd070b..419aa8070e47a 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -171,7 +171,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { assert(arguments != null); browserHistory.setRouteName( arguments!.tryString('location'), - state: arguments.tryString('state'), + state: arguments['state'], replace: arguments.tryBool('replace') ?? false, ); return true; diff --git a/lib/web_ui/test/window_test.dart b/lib/web_ui/test/window_test.dart index 2180f442e7682..9069db61e0b2c 100644 --- a/lib/web_ui/test/window_test.dart +++ b/lib/web_ui/test/window_test.dart @@ -237,6 +237,48 @@ void testMain() { expect(window.browserHistory.urlStrategy!.getPath(), '/foo'); }); + test('should not throw when state is complex json object', + () async { + // Regression test https://github.com/flutter/flutter/issues/87823. + await window.debugInitializeHistory(TestUrlStrategy.fromEntry( + const TestHistoryEntry('initial state', null, '/initial'), + ), useSingle: false); + expect(window.browserHistory, isA()); + + // routeInformationUpdated does not + final Completer callback = Completer(); + window.sendPlatformMessage( + 'flutter/navigation', + const JSONMethodCodec().encodeMethodCall(const MethodCall( + 'routeInformationUpdated', + // ignore: prefer_const_literals_to_create_immutables + { + 'location': '/baz', + 'state': { + 'state1': true, + 'state2': 1, + 'state3': 'string', + 'state4': { + 'substate1': 1.0, + 'substate2': 'string2', + } + }, + }, + )), + (_) { callback.complete(); }, + ); + await callback.future; + expect(window.browserHistory, isA()); + expect(window.browserHistory.urlStrategy!.getPath(), '/baz'); + final dynamic wrappedState = window.browserHistory.urlStrategy!.getState()!; + final dynamic actualState = wrappedState['state']; + expect(actualState['state1'], true); + expect(actualState['state2'], 1); + expect(actualState['state3'], 'string'); + expect(actualState['state4']['substate1'], 1.0); + expect(actualState['state4']['substate2'], 'string2'); + }); + test('can replace in MultiEntriesBrowserHistory', () async { await window.debugInitializeHistory(TestUrlStrategy.fromEntry(