Code Monkey home page Code Monkey logo

stacked-example's Introduction

Stacked Architecture Example

This repo will contain the code for the complete example as it's being developed through the deep dive Flutter Architecture series.

Branches will contain the code at the end of a certain part and master will contain the latest version of the example.

stacked-example's People

Contributors

filledstacks avatar ty4lom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stacked-example's Issues

Form validation.

Hi, it would be nice to have an example on how we can do form validation and map errors from the server to a specific field.

Strange iOS Issues on Latest Flutter Release (1.21.0-6.0.pre.129 - Master Channel)

On the latest release of flutter, I have experienced some really strange behavior. I have the same implementation of the home view + bottom nav as the example, with singleton view models as the nav pages. For the past week+, I have had 0 issues with theming / reactive builds on Dark/Light mode changes on iOS + android.

With this home page setup, and valid, demonstrably working light and dark themes provided to my app, I noticed that on this latest release, as I change the system of my iOS device from Light to Dark mode and vice versa, that the Home View is not responding to those theme / color change events.

This issue does not happen on flutter Master 1.21.0-5.0.pre-37-g35e700518 - I have tested now where upgrading and downgrading flutter is the only change I make, and have identified this to be the root cause of the symptoms I am seeing, but I do not know, however, what the root cause of the actual behavior is.

Hopefully the community can band together and we can figure this weird one out!

Errors when running part one

Currently getting errors when running this source code:

../../../AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/get-1.17.3/lib/src/snackbar/snack_route.dart:279:8: Error: The method 'SnackRoute.install' has more required arguments than those of overridden method 'OverlayRoute.install'. void install(OverlayEntry insertionPoint) { ^ /C:/src/flutter/packages/flutter/lib/src/widgets/routes.dart:46:8: Context: This is the overridden method ('install'). void install() { ^ ../../../AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/get-1.17.3/lib/src/routes/default_route.dart:242:9: Error: No named parameter with the name 'animation'. animation: animation, ^^^^^^^^^ /C:/src/flutter/packages/flutter/lib/src/cupertino/route.dart:542:3: Context: Found this candidate, but the arguments don't match. CupertinoFullscreenDialogTransition({ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../../../AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/get-1.17.3/lib/src/snackbar/snack_route.dart:289:18: Error: Too many positional arguments: 0 allowed, but 1 found. Try removing the extra positional arguments. super.install(insertionPoint);

Any reason as to why this might be the case?

Doubts regarding "Services in Code and how to use them in Flutter" blog post.

This is not an issue but some doubts regarding the blog posts.

  • FutureViewModel - Can we integrate different network requests in a single class?, for example, there are multiple network request should be called at different times, can we put in single Futureviewmodel class.

  • in section Share State / Functionality between ViewModels using Services - can we get the same results by putting API request in corresponding view class instead of service class if data is shared only between two classes.

Partial re-build not working in my setup (given in details)

Hi FilledStacks,
For me partial builds example is not working, that is re-building only one child widget.
Main widget => uses nonReactive constructor (shouldn't rebuilt)
Child widget 1: Using HookViewModelWidget with reactive = false. (shouldn't rebuilt)
Child widget 2: uses ViewModelWidget with reactive = true (should rebuilt)
In my case main widget and both child widgets gets re-built.

I have attached sample dart code and yaml file here.
Thanks a lot in advance.

partial_builds.zip

Error during navigation

After click floatActionButton to navigate I get this error:

E/flutter (14258): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'pushNamed' was called on null.
E/flutter (14258): Receiver: null
E/flutter (14258): Tried calling: pushNamed("/home-view", arguments: null)

I update router.dart:

@MaterialAutoRouter( routes: [ MaterialRoute(page: HomeView), MaterialRoute(page: StartupView, initial: true) ] ) class $Router{}

What I am doing wrong? Thank you.

2022 Code doesn't work anymore, very obsolete

Hello! I managed to run the sample code you provided on this tutorial
(https://github.com/FilledStacks/stacked-example) today, March, 3, 2022 4:59pm,
but it took me 3 hours to update and debug everything before a successful flutter run.
Everything is just very outdated.

I hope you can update the code samples because it's now obsolete :(

Things I did:

  • updated plugins
  • updated auto_route syntax
  • migrated everything to null safe
  • updated variables, null or required

Error when run inside VS code

Launching lib/main.dart on AOSP on IA Emulator in debug mode...
lib/main.dart
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/stacked_services-0.4.11/lib/src/snackbar_service.dart:74:7: Error: Type 'SnackStatusCallback' not found.
SnackStatusCallback onStatusChanged,
^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/stacked_services-0.4.11/lib/src/navigation_service.dart:94:35: Error: The getter 'defaultDurationTransition' isn't defined for the class '_GetImpl'.

  • '_GetImpl' is from 'package:get/get_core/src/get_main.dart' ('../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/get-3.15.0/lib/get_core/src/get_main.dart').
    Try correcting the name to the name of an existing getter, or defining a getter or field named 'defaultDurationTransition'.
    duration: duration ?? Get.defaultDurationTransition,
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    ../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/stacked_services-0.4.11/lib/src/navigation_service.dart:113:33: Error: The getter 'defaultDurationTransition' isn't defined for the class '_GetImpl'.
  • '_GetImpl' is from 'package:get/get_core/src/get_main.dart' ('../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/get-3.15.0/lib/get_core/src/get_main.dart').
    Try correcting the name to the name of an existing getter, or defining a getter or field named 'defaultDurationTransition'.
    duration: duration ?? Get.defaultDurationTransition,
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    ../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/stacked_services-0.4.11/lib/src/snackbar_service.dart:74:7: Error: 'SnackStatusCallback' isn't a type.
    SnackStatusCallback onStatusChanged,
    ^^^^^^^^^^^^^^^^^^^
    ../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/stacked_services-0.4.11/lib/src/snackbar_service.dart:111:9: Error: No named parameter with the name 'onStatusChanged'.
    onStatusChanged: onStatusChanged,
    ^^^^^^^^^^^^^^^
    ../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/get-3.15.0/lib/get_navigation/src/snackbar/snack.dart:12:3: Context: Found this candidate, but the arguments don't match.
    GetBar({
    ^^^^^^

FAILURE: Build failed with an exception.

  • Where:
    Script '/Users/jun/development/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 900

  • What went wrong:
    Execution failed for task ':app:compileFlutterBuildDebug'.

Process 'command '/Users/jun/development/flutter/bin/flutter'' finished with non-zero exit value 1

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 17s
Exception: Gradle task assembleDebug failed with exit code 1
Exited (sigterm)

Services and Testing

Hi,

I'm new to unit testing and I was following your tutorial, but I can't get it to work.

I followed your example:

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:my_app/app/locator.dart';
import 'package:my_app/ui/views/startup/startup_viewmodel.dart';

import '../setup/test_helpers.dart';

void main() {
  group('initialise -', () {
    test('When called should check hasUser on sharedPreferences', () async {
      var sharedPreferences = SharedPrefencesServiceMock();
      locator.registerSingleton<SharedPrefencesServiceMock>(sharedPreferences);
      var model = StartupViewModel();
      await model.initialise();
      verify(sharedPreferences.hasUser);
    });
  });
}

but I get this error:

'package:get_it/get_it_impl.dart': Failed assertion: line 257 pos 14: 'instanceFactory != null': No type SharedPreferencesService is registered inside GetIt.
 Did you forget to pass an instance name? 
(Did you accidentally do  GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;
did you forget to register it?)

and I have no idea what to do.
Can you help me here.

thanks
Steven

How to insert OverlayEntry with Stacked?

Hi,

We're using stacked for a new project and enjoying it so far, but a lot to learn along the way.

One thing we are trying to figure out is the best way to create an OverlayEntry, typicall with a StatefulWidget this would be simple but with stacked we're not sure exactly what to do.

We have this partially working example, which does everything you are not supposed to do with stacked:

import 'package:flutter/material.dart';
import 'package:myapp/models/icons/app_icons.dart';
import 'package:myapp/models/theme/extension.dart';
import 'package:myapp/ui/widgets/top_bar/top_bar_viewmodel.dart';
import 'package:stacked/stacked.dart';

class TopBarView extends StatelessWidget {
  final GlobalKey widgetKey;

  TopBarView({
    @required this.widgetKey,
  });

  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder<TopBarViewModel>.reactive(
      builder: (context, model, child) => Column(
        key: widgetKey,
        children: [
          IntrinsicHeight(
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                // Selected option and chevron
                Expanded(
                  child: TextButton(
                    onPressed: () => model.selectedOptionPressed(widgetKey),
                    child: Container(
                      padding: EdgeInsetsDirectional.only(start: 16, end: 4),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Expanded(
                            child: Text(
                              model.selectedOption,
                              overflow: TextOverflow.fade,
                              maxLines: 1,
                              softWrap: false,
                              style: Theme.of(context).textTheme.headline4,
                            ),
                          ),
                          Icon(
                            AppIcons.chevron_down,
                            size: 24,
                            color: Theme.of(context).own().textColor,
                          )
                        ],
                      ),
                    ),
                  ),
                ),
                // Icon Button
                Container(
                  width: 48,
                  height: 48,
                  decoration: BoxDecoration(
                    color: Theme.of(context).primaryColor,
                  ),
                  child: TextButton(
                    child: Icon(
                      AppIcons.search,
                      size: 24,
                      color: Theme.of(context).backgroundColor,
                    ),
                    onPressed: model.iconPressed,
                  ),
                ),
              ],
            ),
          ),
          Container(
            width: double.infinity,
            height: 1,
            decoration: BoxDecoration(
              color: Theme.of(context).own().dividerColor,
            ),
          ),
        ],
      ),
      viewModelBuilder: () => TopBarViewModel(context: context),
    );
  }
}

And then ViewModel

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:myapp/models/theme/extension.dart';
import 'package:stacked/stacked.dart';

class TopBarViewModel extends BaseViewModel {
  final BuildContext context;

  TopBarViewModel({@required this.context});

  String _selectedOption = "an option";
  String get selectedOption => _selectedOption;

  bool _isOpen = false;
  bool get isOpen => _isOpen;

  RenderBox _renderBox;
  Offset _offset;
  OverlayEntry _dropdownOverlay;

  void selectedOptionPressed(GlobalKey widgetKey) {
    _renderBox = widgetKey.currentContext.findRenderObject();
    _offset = _renderBox.localToGlobal(Offset.zero);
    print(_renderBox.size.height);
    print(_renderBox.size.width);
    print(_offset.dx);
    print(_offset.dy);
    _isOpen = !_isOpen;

    if (_isOpen) {
      _dropdownOverlay = _topBarOverlayWidget();
      Overlay.of(context).insert(_dropdownOverlay);
    } else {
      _dropdownOverlay.remove();
    }
  }

  OverlayEntry _topBarOverlayWidget() {
    return OverlayEntry(builder: (context) {
      return Positioned(
        top: _offset.dy + _renderBox.size.height,
        left: _offset.dx,
        width: _renderBox.size.width,
        child: Container(
          height: 200,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(
                Theme.of(context).own().radiusLg,
              ),
              bottomRight: Radius.circular(
                Theme.of(context).own().radiusLg,
              ),
            ),
            boxShadow: [Theme.of(context).own().shadowTopBarDropdown],
            color: Theme.of(context).backgroundColor,
          ),
        ),
      );
    });
  }

  void iconPressed() {}
}

Hoping for some insight as to what the right way to do this with stacked would be, thanks in advance for any insight!

Issues running with the latest Flutter 1.22

This app has been very handy to see a working stacked app with a recent and happily coexisting set of dependencies. Looks like there are a variety of issues running against the latest Flutter release. And also against current versions of key libraries like Milad-Akarie/auto_route_library#250

It would be a huge help if someone from the core stacked team could do some freshening on this app so that it worked with the latest. And where 3rd party libs are not the latest, if that is intentional and for good reasons, knowing why would be also helpful so that we don't continue to waste time trying to get everything to work together.

Btw, huge fan of Stacked here. I'm still a relative newbie though or I'd do this myself. Few hours wasted trying...

Stu

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.