Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple BeamLocations with same subclass breaks page rendering. #658

Open
jwalton opened this issue Feb 16, 2024 · 1 comment
Open

Multiple BeamLocations with same subclass breaks page rendering. #658

jwalton opened this issue Feb 16, 2024 · 1 comment

Comments

@jwalton
Copy link

jwalton commented Feb 16, 2024

Describe the bug

If you have two ore more BeamLocations that are of the same subclass, page rendering is broken. Navigating to links works, but the content on screen doesn't change.

Beamer version: 1.6.0

To Reproduce

This creates two instances of SimpleLocation, which is just a BeamLocation where you pass in a path pattern, a key, and a child. The two SimpleLocations ought to allow routing to /a and /b, but it doesn't work. If you try to click the button to go to "/b", the URL changes if you're on Web, but the content of the page doesn't change.

If you copy-paste the SimpleLocation class to a SimpleLocation2 class, and change the "BScreen" route to use SimpleLocation2, the app will start working as expected. Somehow having two BeamLocations that are instances of the same class breaks page rendering.

import 'package:beamer/beamer.dart';
import 'package:flutter/material.dart';

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

class SimpleLocation extends BeamLocation<BeamState> {
  final List<String> _pathPatterns;
  final ValueKey _key;
  final Widget child;

  SimpleLocation(String path, String key, this.child)
      : _pathPatterns = [path],
        _key = ValueKey(key);

  @override
  List<String> get pathPatterns => _pathPatterns;

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      BeamPage(
        key: _key,
        child: child,
      ),
    ];
  }
}

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

  final routerDelegate = BeamerDelegate(
    initialPath: '/a',
    // locationBuilder: RoutesLocationBuilder(
    //   routes: {
    //     // Return either Widgets or BeamPages if more customization is needed
    //     '/a': (context, state, data) => AScreen(),
    //     '/b': (context, state, data) => BScreen(),
    //   },
    // ),
    locationBuilder: BeamerLocationBuilder(
      beamLocations: [
        SimpleLocation('/a', 'a', AScreen()),
        SimpleLocation('/b', 'b', BScreen()),
      ],
    ).call,
  );
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      routeInformationParser: BeamerParser(),
      routerDelegate: routerDelegate,
    );
  }
}

class AScreen extends StatelessWidget {
  AScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('A Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Beamer.of(context).beamToNamed('/b');
          },
          child: const Text('Go to B'),
        ),
      ),
    );
  }
}

class BScreen extends StatelessWidget {
  BScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('B Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Beamer.of(context).beamToNamed('/a');
          },
          child: const Text('Go to A'),
        ),
      ),
    );
  }
}

Expected behavior

BeamLocations should work.

@stan-at-work
Copy link

Describe the bug

If you have two ore more BeamLocations that are of the same subclass, page rendering is broken. Navigating to links works, but the content on screen doesn't change.

Beamer version: 1.6.0

To Reproduce

This creates two instances of SimpleLocation, which is just a BeamLocation where you pass in a path pattern, a key, and a child. The two SimpleLocations ought to allow routing to /a and /b, but it doesn't work. If you try to click the button to go to "/b", the URL changes if you're on Web, but the content of the page doesn't change.

If you copy-paste the SimpleLocation class to a SimpleLocation2 class, and change the "BScreen" route to use SimpleLocation2, the app will start working as expected. Somehow having two BeamLocations that are instances of the same class breaks page rendering.

import 'package:beamer/beamer.dart';

import 'package:flutter/material.dart';



void main() {

  runApp(MyApp());

}



class SimpleLocation extends BeamLocation<BeamState> {

  final List<String> _pathPatterns;

  final ValueKey _key;

  final Widget child;



  SimpleLocation(String path, String key, this.child)

      : _pathPatterns = [path],

        _key = ValueKey(key);



  @override

  List<String> get pathPatterns => _pathPatterns;



  @override

  List<BeamPage> buildPages(BuildContext context, BeamState state) {

    return [

      BeamPage(

        key: _key,

        child: child,

      ),

    ];

  }

}



class MyApp extends StatelessWidget {

  MyApp({super.key});



  final routerDelegate = BeamerDelegate(

    initialPath: '/a',

    // locationBuilder: RoutesLocationBuilder(

    //   routes: {

    //     // Return either Widgets or BeamPages if more customization is needed

    //     '/a': (context, state, data) => AScreen(),

    //     '/b': (context, state, data) => BScreen(),

    //   },

    // ),

    locationBuilder: BeamerLocationBuilder(

      beamLocations: [

        SimpleLocation('/a', 'a', AScreen()),

        SimpleLocation('/b', 'b', BScreen()),

      ],

    ).call,

  );

  // This widget is the root of your application.

  @override

  Widget build(BuildContext context) {

    return MaterialApp.router(

      title: 'Flutter Demo',

      theme: ThemeData(

        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),

        useMaterial3: true,

      ),

      routeInformationParser: BeamerParser(),

      routerDelegate: routerDelegate,

    );

  }

}



class AScreen extends StatelessWidget {

  AScreen({super.key});



  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: const Text('A Screen'),

      ),

      body: Center(

        child: ElevatedButton(

          onPressed: () {

            Beamer.of(context).beamToNamed('/b');

          },

          child: const Text('Go to B'),

        ),

      ),

    );

  }

}



class BScreen extends StatelessWidget {

  BScreen({super.key});



  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: const Text('B Screen'),

      ),

      body: Center(

        child: ElevatedButton(

          onPressed: () {

            Beamer.of(context).beamToNamed('/a');

          },

          child: const Text('Go to A'),

        ),

      ),

    );

  }

}

Expected behavior

BeamLocations should work.

Yea, this code example should work, its weard that is doesn't.

I will look in to it 👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants