-
-
Notifications
You must be signed in to change notification settings - Fork 124
Open
Description
Describe the bug
When using RoutesLocationBuilder, Beamer is confusing fixed routes with dynamic routes.
'/'
'/books'
'/books/create'
'/books/:bookId'
If we call context.beamToNamed('/books/create') beamer confuses the word 'create' with the parameter :bookId.
Beamer version: v1.7.0, master
To Reproduce
Steps to reproduce the behavior:
- Copy and Simulate the code below
- Put breakpoints on each return BeamPage
- Click on Create Book button
- At the last breakpoint, see the error that the word 'create' is confused with the parameter :bookId
Expected behavior
Beamer should differentiate fixed routes from dynamic routes. The method context.beamToNamed('/books/create') should return the correct beamPage without confusion with '/books/:bookId' .
Screenshots
Smartphone:
- Device: Galaxy S24 FE - SM S721B
- Device: Redmi Note 6 Pro
- Simulator: Pixel 3a XL API 30
Additional context
Don't forget we are using RoutesLocationBuilder.
Example
import 'package:flutter/material.dart';
import 'package:beamer/beamer.dart';
// DATA
class Book {
const Book(this.id, this.title, this.author);
final int id;
final String title;
final String author;
}
const List<Book> books = [
Book(1, 'Stranger in a Strange Land', 'Robert A. Heinlein'),
Book(2, 'Foundation', 'Isaac Asimov'),
Book(3, 'Fahrenheit 451', 'Ray Bradbury'),
];
// SCREENS
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Screen'),
),
body: Column(
children: [
Center(
child: ElevatedButton(
onPressed: () => context.beamToNamed('/books'),
child: const Text('See books'),
),
),
Center(
child: ElevatedButton(
onPressed: () => context.beamToNamed('/books/create'),
child: const Text('create book'),
),
),
],
),
);
}
}
class BooksScreen extends StatelessWidget {
const BooksScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Books'),
),
body: ListView(
children: books
.map(
(book) => ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => context.beamToNamed('/books/${book.id}'),
),
)
.toList(),
),
);
}
}
class BookDetailsScreen extends StatelessWidget {
const BookDetailsScreen({super.key, required this.book});
final Book? book;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(book?.title ?? 'Not Found'),
),
body: book != null
? Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Author: ${book!.author}'),
)
: const SizedBox.shrink(),
);
}
}
class BookCreateScreen extends StatelessWidget {
const BookCreateScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Book Create'),
),
body: Center(
child: Text('create a book here'),
));
}
}
// APP
class MyApp extends StatelessWidget {
MyApp({super.key});
final routerDelegate = BeamerDelegate(
locationBuilder: RoutesLocationBuilder(
routes: {
'/': (_, __, ___) {
return const BeamPage(
key: ValueKey(''), title: 'Home', child: HomeScreen());
},
'/books': (_, __, ___) {
return const BeamPage(
key: ValueKey('books'), title: 'Books', child: BooksScreen());
},
'/books/create': (_, __, ___) {
return BeamPage(
key: ValueKey('book-create'),
title: 'Book create',
child: BookCreateScreen());
},
'/books/:bookId': (_, state, ___) {
final String bookIdParameter = state.pathParameters['bookId']!;
final bookId = int.parse(bookIdParameter);
final book = books.firstWhere((book) => book.id == bookId);
return BeamPage(
key: ValueKey('book-$bookIdParameter'),
title: 'Book #$bookIdParameter',
child: BookDetailsScreen(book: book));
},
},
).call,
notFoundRedirectNamed: '/books',
);
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: routerDelegate,
routeInformationParser: BeamerParser(),
backButtonDispatcher:
BeamerBackButtonDispatcher(delegate: routerDelegate),
);
}
}
void main() => runApp(MyApp());
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
