Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 10:12
    SaurabhSM commented #280
  • Dec 06 19:36
    gcacoutinho commented #280
  • Dec 05 18:42
    SaurabhSM opened #280
  • Dec 04 19:50
    codecov-io commented #243
  • Dec 04 19:50
    rrousselGit synchronize #243
  • Dec 04 19:50

    rrousselGit on v4.0.0

    markNeedsNotifyDependents is no… (compare)

  • Dec 04 18:44
    wpietri commented #140
  • Dec 04 18:41
    rrousselGit commented #140
  • Dec 04 18:31
    wpietri commented #140
  • Dec 03 23:11
    rrousselGit commented #244
  • Dec 03 23:11
    rrousselGit commented #244
  • Dec 03 23:11
    rrousselGit commented #244
  • Dec 03 22:16
    rrousselGit commented #244
  • Dec 03 22:16
    rrousselGit commented #244
  • Dec 03 22:07
    rrousselGit commented #244
  • Dec 03 20:56
    rrousselGit labeled #279
  • Dec 03 20:56
    rrousselGit milestoned #279
  • Dec 03 20:56
    rrousselGit commented #279
  • Dec 03 19:55
    chinnonsantos closed #277
  • Dec 03 19:55
    chinnonsantos commented #277
Joe Lapp
@jtlapp
But somehow a letter got deleted in the copy. Pressing the floating action button creates a NewItemScreen not a NewItemcreen.
Remi Rousselet
@rrousselGit
Right, but what's the problem?
Joe Lapp
@jtlapp
I guess if you'd do it this way too, then there is no problem. It just seems unnecessarily redundant.
Matt Russell
@mattrussell-sonocent
I'm trying to write a widget test around a bit of UI that involves a ChangeNotifierProvider<EventsModel>.value(value: _eventsModel) / Provider.of<EventsModel>(context) pair. After causing EventsModel to change in my test (and hence call notifyListeners), I don't see a triggered build of the consuming widget occurring during the test, although that works fine when running the actual app. Any ideas on what might be going on? I've tried calling tester.pumpAndSettle.
Matt Russell
@mattrussell-sonocent
^^ actually, I think I've found the problem, just a missing bit of plumbing on my part, apologies for the noise
Joe Lapp
@jtlapp

I just discovered that asking for a value with listen: false is vastly more expensive than asking with listen: true. From the description of ancestorWidgetOfExactType(): "Calling this method is relatively expensive (O(N) in the depth of the tree). Only call this method if the distance from this widget to the desired ancestor is known to be small and bounded."

Meanwhile, inheritFromWidgetOfExactType() is only O(1): "Calling this method is O(1) with a small constant factor, but will lead to the widget being rebuilt more often."

I now wonder if I ought to choose some sort of global scheme over using listen: false.
Joe Lapp
@jtlapp
Oh never mind. It can't hurt to use listen: true on a value that never changes. But this means that I shouldn't think of the listen parameter as being used just to "listen."
Remi Rousselet
@rrousselGit
Provider doesn't use ancestorWidgetOfExactType
It uses ancestorInheritedElementForWidgetOfExactType
Joe Lapp
@jtlapp
And that's O(1). Thanks for the correction. What a long name!
Preet Parekh
@preetjdp
What's the best way to Proxy Provide a Stream Provider?
Remi Rousselet
@rrousselGit
Hardly feasible in a generic way at the moment.
Instead you can make a StatefulWidget and use DidChangeDependencies
Joe Lapp
@jtlapp

I wanted to inject an object into descendent widgets and so used Provider.value. However, because this object implements ChangeNotifier, Provider threw an exception telling me to use something like ChangeNotifierProvider instead. Well, I'm injecting for the purpose of posting information to the object, not for the purpose of displaying anything in the object. I can easily change it to ChangeNotifierProvider and not have to worry about anything rebuilding (because there's nothing to rebuild), but I do feel the need to include a comment saying not to be deceived, that the object is not inducing rebuilds in any dependents.

It's not an ideal situation. Is there a better way to provide an object that changes in one context but not in the current context?

Remi Rousselet
@rrousselGit
There 's a static method on provider that you can use to tweak the assertion
Joe Lapp
@jtlapp

It looks like you mean doing this:
Provider.debugCheckInvalidValueType = null

That would turn off the check everywhere. It would be nice to selectively shut it off.

Remi Rousselet
@rrousselGit
You don't have to set it to null. Replace it with your own
You can wrap the previous implementation in something like:
final previous = Provider.debugCheckInvalidValueType

Provider.debugCheckInvalidValueType = <T>(T value) {
 if (value is My Notifier) return;
 previous<T>(value);
}
This will alow MyNotifier to be used on Provider without allowing the classic ChangeNotifier
Joe Lapp
@jtlapp
I just deleted two responses. I think I understand now. Adding this would allow me to use this particular class with Provider.value even if it also drops type checking for the class.
Thank you so much!
Joe Lapp
@jtlapp
Okay, only one thing annoying about that solution. I had to add it to all of my tests. Otherwise works great. Thank you!
Elango
@elangora_twitter
Hi @rrousselGit I have a large enterprise app, the submodules are built as plugins. Any idea how I can communicate from Main app to plugins and vice-versa. Any guidence will be helpful. Using provider package
Preet Parekh
@preetjdp
@elangora_twitter Could you share some samples of what you're trying to achieve?
Rolly Peres
@RollyPeres
@rrousselGit Hi, any input on rrousselGit/provider#267 ?
Remi Rousselet
@rrousselGit
Rolly: I don't see anything obvious, and am a bit too lazy to test :p
Rolly Peres
@RollyPeres
@rrousselGit LOL. I really appreciate your honesty 🤣
It's a thing related to a feature I'm working on at work. I'm trying to push provider package as a standard here. I'd be really grateful if you could take a look when you get the time. I'm sick of these people using setState all over the place 😒
webskydavid
@webskydavid
@RollyPeres Provider.of<DataNotifier>(context, listen: false).removeItem(), did you try to change it to true?
Why you use in this callback Provider.of? You could also use directlly the the model parameter
Rolly Peres
@RollyPeres
@webskydavid listen: false since I'm only calling some method on the notifier, so there's no point in listening there.
That's just a small example, in the actual app the call is actually deeper in the widget tree.
webskydavid
@webskydavid
It seams like the problem occures in the _handleTap method with Navigator in the DropDownButton. Like you mentioned early . Try to build your own dropdown ;) Maybe there are some packages that don't use Navigator as an handler.
Rolly Peres
@RollyPeres
Ye, it's pretty weird @webskydavid :|
Alican YILDIZ
@anotherglitchinthematrix
Hello, I have this simplified provider to manage authentication on my app.
My problem is, on application's first start I'm seeing AuthenticationProvider created twice. You can observe this behavior on the debug console "An AuthenticationProvide instance is created" printed twice.
Is this expected and good to go? What's causing this and is it correct approach to wrap the MaterialApp with a consumer?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class AuthenticationProvider extends ChangeNotifier {
  AuthenticationProvider() {
    print('An AuthenticationProvide instance is created');
  }

  bool get isAuthenticated => true;
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<AuthenticationProvider>.value(
          value: AuthenticationProvider(),
        )
      ],
      child: Consumer<AuthenticationProvider>(
        builder: (_, authentication, __) {
          return MaterialApp(
            home: authentication.isAuthenticated ? Home() : Login(),
          );
        },
      ),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Hey there'),
      ),
    );
  }
}

class Login extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('Login Page'),
      ),
    );
  }
}
webskydavid
@webskydavid
@anotherglitchinthematrix Hi, I suggest to use Consumer inside of the child widgets not directly with MeterialApp. Create a Wrapper for authentication where you check if user is loggedin.
Alican YILDIZ
@anotherglitchinthematrix
Thank you for suggestion, but it seems AuthenticationProvider still created twice, so it seems MultiProvider's itself causing this behaviour, I even tried it without wrapping with a consumer.
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<AuthenticationProvider>.value(
          value: AuthenticationProvider(),
        )
      ],
      child: MaterialApp(
        home: Login(),
      ),
    );
  }
}
Alican YILDIZ
@anotherglitchinthematrix
Serving the providers list as a final variable outside of the build methodsolved the problem for me. It seems like MaterialApp causing the built twice even in a simple trivial app (without provider) this behaviour can be observed.
class App extends StatelessWidget {
  final providers = <SingleChildCloneableWidget>[
    ChangeNotifierProvider<AuthenticationProvider>.value(
      value: AuthenticationProvider(),
    )
  ];
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: providers,
      child: Consumer<AuthenticationProvider>(
        builder: (_, authentication, __) {
          return MaterialApp(
            home: authentication.isAuthenticated ? Home() : Login(),
          );
        },
      ),
    );
  }
}
webskydavid
@webskydavid
@anotherglitchinthematrix Good to know :) Thx
webskydavid
@webskydavid
Hi everyone, did you notice in provider that updating list item does not cause list rerender?
For example:
If I try to change one of the object in a List with map() method the view does not rerender. I use after map() the notifyListeners() of course.
Remi Rousselet
@rrousselGit
Setting providers outside of build is anti pattern
You should use the default constructor of providers instead
Alican YILDIZ
@anotherglitchinthematrix
Hmm, in that case how can I prevent the unnecessary creation of the providers second time when the MaterialApp force to rebuild the App on it's initialization. Or should I prevent that? And would it be still bad practice if I use my authentication provider like in the example below. My AuthenticationProvider doing a heavylifting on app start while trying to fetch the users from local database, so I really don't want it to be created twice;
class App extends StatelessWidget {

  final authenticationProvider = AuthenticationProvider();

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<AuthenticationProvider>.value(
          value: authenticationProvider,
        )
      ],
      child: Consumer<AuthenticationProvider>(
        builder: (_, authentication, __) {
          return MaterialApp(
            home: authentication.isAuthenticated ? Home() : Login(),
          );
        },
      ),
    );
  }
}
Alican YILDIZ
@anotherglitchinthematrix
@webskydavid can you share a simplified example?
webskydavid
@webskydavid
@anotherglitchinthematrix Yes, one moment

Here is the provider method to update item in list.

Future<void> update(String id, String userId, String start) async {
    setBusy(true);

    String url = '${urlPath}list/update/$id';

    try {
      await Future.delayed(Duration(milliseconds: 3000));
      http.Response res =
          await _http.put(url, body: {'userId': userId, 'start': start});

      var data = json.decode(res.body);
      if (res.statusCode == 201) {
        List<Gofl> newAll = [];
        for (Gofl a in _all) {
          if (a.id == id) {
            newAll.add(Gofl.fromJson(data['data']));
          }
          newAll.add(a);
        }
        _all = [...[], ...newAll];
      } else {
        setError(data['message']);
      }
    } catch (e) {
      setError(e.toString());
    }
    setBusy(false);
  }

And this is the widget that initialise the list fetching.

class _ListBuilderState extends State<ListBuilder> {
  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero).then((_) {
      Provider.of<GoflProvider>(context, listen: false).list();
    });
  }

  @override
  Widget build(BuildContext context) {
    print('ListBuilder build()');
    return Consumer<GoflProvider>(
      builder: (context, gofl, _) {
        print('Consumer render list');
        return Center(
          child: list(gofl.all),
        );
      },
    );
  }
list(){
// ...
}
}
webskydavid
@webskydavid
Inside of the list I have a check if user is the owner of the item. But it seams that after rebuilding the check method does not run correctly
webskydavid
@webskydavid
I fixed it by moving form List to Map