Giter Site home page Giter Site logo

Deep Location problem about beamer HOT 2 CLOSED

csinesz avatar csinesz commented on August 17, 2024 1
Deep Location problem

from beamer.

Comments (2)

slovnicki avatar slovnicki commented on August 17, 2024 1

@csinesz thanks for reporting this. From the top of my head, I think it's a problem related to something I was trying to solve yesterday (and thought I solved it, but was aware that solution is not ideal). I will test your example and try to fix this today.

from beamer.

slovnicki avatar slovnicki commented on August 17, 2024

I solved it, but it's a tricky use case and I'm not sure (yet) how to solve it better at the moment.

First, I noticed you forgot to put BooksThirdLocation() in Beamer.beamLocations, but that did not affect the nature of issue.

The problem was that both BooksLocation and BooksThirdLocation were compared to current stack of pages, but without any pathParameters. At this state then, they are the same. But, the solution was not just to compare everytime with pathParameters because then BooksLocation can never go to just /books without the id part.

So, I added an attribute called keepPathParametersOnPop (default false) to the BeamPage and then BooksThirdLocation should set it to true. In fact, any location that has pages beyond/after :id/ should set this to true.

I also refactored your BooksThirdLocation a little bit to be simpler. Notice that collection-if is not necessary on last BeamPage because there can not be a situation where :id doesn't exists when we're on books/:id/redeem. Because, what would that be... books//redeem? :)

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

// SCREENS
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () => context.beamTo(BooksLocation()),
          child: Text('Go to books location'),
        ),
      ),
    );
  }
}

const List<Map<String, String>> books = [
  {
    'id': '1',
    'title': 'Stranger in a Strange Land',
    'author': 'Robert A. Heinlein',
  },
  {
    'id': '2',
    'title': 'Foundation',
    'author': 'Isaac Asimov',
  },
  {
    'id': '3',
    'title': 'Fahrenheit 451',
    'author': 'Ray Bradbury',
  },
];

class BooksScreen extends StatelessWidget {
  BooksScreen({this.titleQuery = ''});

  final String titleQuery;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Books'),
      ),
      body: ListView(
        children: books
            .where((book) =>
                book['title'].toLowerCase().contains(titleQuery.toLowerCase()))
            .map((book) => ListTile(
                  title: Text(book['title']),
                  subtitle: Text(book['author']),
                  onTap: () => Beamer.of(context).beamTo(
                    BooksLocation.withParameters(
                      path: {'id': book['id']},
                    ),
                  ),
                ))
            .toList(),
      ),
    );
  }
}

class BookDetailsScreen extends StatelessWidget {
  BookDetailsScreen({
    this.book,
  });

  final Map<String, String> book;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(book['title']),
      ),
      body: Column(
        children: [
          Text('Author: ${book['author']}'),
          SizedBox(
            height: 50.0,
          ),
          ElevatedButton(
            child: Text('GO DEEPER -> '),
            onPressed: () {
              Beamer.of(context).beamTo(
                BooksThirdLocation.withParameters(
                  path: {'id': book['id']},
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

class BookThirdScreen extends StatelessWidget {
  BookThirdScreen({
    this.book,
  });

  final Map<String, String> book;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(book['title']),
      ),
      body: Text('Third screen of book nr. ${book['author']}'),
    );
  }
}

// LOCATIONS
class HomeLocation extends BeamLocation {
  @override
  List<BeamPage> get pages => [
        BeamPage(
          key: ValueKey('home'),
          page: HomeScreen(),
        ),
      ];

  @override
  String get pathBlueprint => '/';
}

class BooksLocation extends BeamLocation {
  BooksLocation() : super();

  BooksLocation.withParameters({
    Map<String, String> path,
    Map<String, String> query,
  }) : super.withParameters(path: path, query: query);

  @override
  List<BeamPage> get pages => [
        ...HomeLocation().pages,
        BeamPage(
          key: ValueKey('books-${queryParameters['title'] ?? ''}'),
          page: BooksScreen(
            titleQuery: queryParameters['title'] ?? '',
          ),
        ),
        if (pathParameters.containsKey('id'))
          BeamPage(
            key: ValueKey('book-${pathParameters['id']}'),
            page: BookDetailsScreen(
              book: books
                  .firstWhere((book) => book['id'] == pathParameters['id']),
            ),
          ),
      ];

  @override
  String get pathBlueprint => '/books/:id';
}

class BooksThirdLocation extends BeamLocation {
  BooksThirdLocation() : super();

  BooksThirdLocation.withParameters({
    Map<String, String> path,
    Map<String, String> query,
  }) : super.withParameters(path: path, query: query);

  @override
  List<BeamPage> get pages => [
        ...BooksLocation.withParameters(
          path: pathParameters,
          query: queryParameters,
        ).pages,
        BeamPage(
          key: ValueKey('book-deeper-${pathParameters['id']}'),
          keepPathParametersOnPop: true,
          page: BookThirdScreen(
            book:
                books.firstWhere((book) => book['id'] == pathParameters['id']),
          ),
        ),
      ];

  @override
  String get pathBlueprint => '/books/:id/deeper';
}

// APP
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Beamer(
      initialLocation: HomeLocation(),
      beamLocations: [
        HomeLocation(),
        BooksLocation(),
        BooksThirdLocation(),
      ],
      notFoundPage: Scaffold(body: Center(child: Text('Not found'))),
      app: MaterialApp(),
    );
  }
}

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

Let me know of any other issues you may encounter.

from beamer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.