Coder Social home page Coder Social logo

Comments (15)

rrousselGit avatar rrousselGit commented on July 20, 2024 2

Tim is correct, modulo the fact that you don't have to listen to the texteditingcontroller

You can use Textfield.onChange:

final filterProvider = StateProvider((_) => '');

... 
Textfield(
  onChange: (value) => filterProvider.read(context).state = value, 
)

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024 2

Feel free to make a proposal about such helpers, although I'm not entirely convinced. It sounds like this is more about people not knowing how to use the tools available than a need for a new tool.
And adding new APIs is difficult as they require a lot of effort to maintain.

Overall: Tutorials, articles, a search bar, and more examples are planned.
They should come right after the big PR gets merged, so August I'd say

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024

Computed.family as you've described should work.

I'm not sure why it doesn't in your case. Try a flutter clean?

from riverpod.

zgramming avatar zgramming commented on July 20, 2024

@rrousselGit strangely , after flutter clean and try uninstall application. it doesn't work what as expected.

Expectation

Result data when typing will be seen immediately.

Reality

It will show data when keyboard closed, and i think data show when keyboard close because when keyboard close it will rebuild entire widget. You can see my Gif implementation.
I missed something ?

tanya riverpod 4

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024

Have you tried printing the unfiltered list, to see if it changes?

from riverpod.

TimWhiting avatar TimWhiting commented on July 20, 2024

I believe the issue is that you are watching the family provider, but you aren't rebuilding when the queryController.text changes so it isn't getting the new computed. So you probably want to listen to the controller and rebuild based on that as well? I'm not sure if there is a better solution though.

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024

Oh that's possible.

A solution is to save the filter in a StateProvider, then instead of a Computed.family, have a simple Computed that reads the filter

from riverpod.

zgramming avatar zgramming commented on July 20, 2024

Another testing for make it sure.


class TestingFilterModel {
  String id;
  String name;
  int price;
  TestingFilterModel({this.id, this.name, this.price});
}

class TestingFilterProvider extends StateNotifier<List<TestingFilterModel>> {
  TestingFilterProvider([List<TestingFilterModel> state]) : super(state ?? []);
}

final testingFilterProvider = StateNotifierProvider<TestingFilterProvider>((ref) {
  return TestingFilterProvider([
    TestingFilterModel(id: '1', name: 'chair', price: 20000),
    TestingFilterModel(id: '2', name: 'book', price: 50000),
    TestingFilterModel(id: '3', name: 'handphone', price: 1000),
    TestingFilterModel(id: '4', name: 'money', price: 60000),
    TestingFilterModel(id: '5', name: 'bycle', price: 88000),
  ]);
});

final filterTesting = Computed.family<List<TestingFilterModel>, String>((read, query) {
  final testing = read(testingFilterProvider.state);
  return testing.where((element) => element.name.toLowerCase().contains(query)).toList();
});



Consumer((ctx, read) {
              // final utang = read(showFilteredList(_queryController.text));
              final filter = read(filterTesting(_queryController.text));
              return Expanded(
                child: ListView.separated(
                  shrinkWrap: true,
                  itemCount: filter.length,
                  separatorBuilder: (BuildContext context, int index) {
                    return Divider();
                  },
                  itemBuilder: (BuildContext context, int index) {
                    final result = filter[index];
                    return Card(
                      child: Center(
                        // child: Text(result.pengutang.nameUser),
                        child: Text(result.name),
                      ),
                    );
                  },
                ),
              );
            }),

from riverpod.

zgramming avatar zgramming commented on July 20, 2024

@rrousselGit can you give me example to implement that ? Because i don't get what you think.
Because in documentation , Computed don't have parameter to send right ? the option my understanding is Computed.Family / Provider.Family

@TimWhiting problem is in my code because it not rebuild the state ?

from riverpod.

TimWhiting avatar TimWhiting commented on July 20, 2024

Yes, the problem as it currently stands is in your code. However, you can use Remy's suggestion to make it work without a manual rebuild on a listener on your controller.

class TestingFilterModel {
  String id;
  String name;
  int price;
  TestingFilterModel({this.id, this.name, this.price});
}

class TestingFilterProvider extends StateNotifier<List<TestingFilterModel>> {
  TestingFilterProvider([List<TestingFilterModel> state]) : super(state ?? []);
}

final testingFilterProvider = StateNotifierProvider<TestingFilterProvider>((ref) {
  return TestingFilterProvider([
    TestingFilterModel(id: '1', name: 'chair', price: 20000),
    TestingFilterModel(id: '2', name: 'book', price: 50000),
    TestingFilterModel(id: '3', name: 'handphone', price: 1000),
    TestingFilterModel(id: '4', name: 'money', price: 60000),
    TestingFilterModel(id: '5', name: 'bycle', price: 88000),
  ]);
});
/// No longer a family computed
final filterTesting = Computed<List<TestingFilterModel>>((read) {
  final testing = read(testingFilterProvider.state);
/// Now using filter from a filterProvider
  final filter = read(filterProvider);
  return testing.where((element) => element.name.toLowerCase().contains(filter)).toList();
});
/// filter provider initialized with empty string
final filterProvider = StateProvider((ref) => '');

/// In your widget
// Somewhere you need to put something like this. (Probably in initState if you aren't using hook widgets). 
// filterprovider state set to the new filter based on your filter text controller
// DON'T put this in your build method, since you don't want to create a new listener every build. Memory leak
_controller.listen((value) => context.read(filterProvider).state = value);
// If using hook widgets you can probably use useEffect

Consumer((ctx, read) {

              final filter = read(filterTesting);
              return Expanded(
                child: ListView.separated(
                  shrinkWrap: true,
                  itemCount: filter.length,
                  separatorBuilder: (BuildContext context, int index) {
                    return Divider();
                  },
                  itemBuilder: (BuildContext context, int index) {
                    final result = filter[index];
                    return Card(
                      child: Center(
                        child: Text(result.name),
                      ),
                    );
                  },
                ),
              );
            }),

I haven't tested this so it might have some issues. But this is the general idea.

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024

Both the Todos and the Marvel example implement a filter.
The former uses an enum as filter, while the latter has a search field.

from riverpod.

zgramming avatar zgramming commented on July 20, 2024

Ahhh finally i get it. Thank's @rrousselGit and @TimWhiting for both of you to help my case.

from riverpod.

TimWhiting avatar TimWhiting commented on July 20, 2024

@rrousselGit I wonder for some common design patterns like filtering etc, there could be some helper functions (Maybe in another package). Or another provider for filtering that wraps a StateProvider for the filter and a Computed for the filtered results. I know you are planning on creating a retry variant for that common use case, so maybe a filter variant of a provider would be another good common use case to look at?

I'd be willing to help with creating some convenient providers/functions for common use cases and make a few PRs. But I'll probably wait for your reworked version to come out before looking into that.

from riverpod.

rrousselGit avatar rrousselGit commented on July 20, 2024

What would helpers for filter looks like?
In my opinion, Computed is the helper (especially combined with StateProvider)

What do you think is missing?

from riverpod.

TimWhiting avatar TimWhiting commented on July 20, 2024

The problem isn't necessarily a feature issue, more of a discoverability issue I think. When you are thinking of a filter feature for your app you aren't necessarily thinking in terms of providers and computed. You have to switch mentalities to try to think how to implement it. So it wouldn't necessarily be a different provider, just some convenience functions or hooks that are in the terminology you would use when describing a filter.
i.e.

final myFilter = createFilterProvider(initialQuery: () => '', filter: (ref, query) => //do filter stuff here
);

/// In hook widget
final filter = useFilter(myFilter);

// Changing query
TextField(onChange: (value) => filter.query = value),
// Using filter state
Column(children: filter.state.map(...).toList()),

I'm pretty busy this week, but I can try to prototype such a function / provider. Essentially what gets returned from the function is not a provider but something like this:

class FilterProviderHelper<Query extends StateNotifier, Filter extends Computed> {
   final Query queryProvider;
   final Filter filterProvider;
   FilterProviderHelper(this.queryProvider, this.filterProvider);
}

And the hook functions access the relevant portions of this class.

As a side note.
Note that I say discoverability issue, not example/documentaion issue, I know you have examples for it, but I think people don't necessarily look at examples on GitHub. I used to use Bloc before starting to migrate my stuff over to StateNotifier + Freezed + Hooks + Riverpod. I liked the tutorial section of the Bloc documentation: for example: https://bloclibrary.dev/#/fluttertodostutorial. Tutorials are longer than simple examples, but they showcase some design patterns & how to think when working with the API. I'd be willing to turn your todo example into a tutorial for the riverpod website. But it might take a little bit of time.

In general I'd love to see more content, such as a Medium article or YouTube series showing how to use the combination of (StateNotifier + Freezed + Hooks + Riverpod). I really love how they all work together. Again, I'd be willing to do this, but need to find / set aside time for it & this week is going to be pretty busy for me already.

from riverpod.

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.