Comments (15)
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.
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.
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.
@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 ?
from riverpod.
Have you tried printing the unfiltered list, to see if it changes?
from riverpod.
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.
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.
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.
@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.
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.
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.
Ahhh finally i get it. Thank's @rrousselGit and @TimWhiting for both of you to help my case.
from riverpod.
@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.
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.
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)
- ImageProvider generated as InvalidType HOT 4
- `AutoDisposeProvider` is getting disposed when watched in a `StreamProvider` using `async*` HOT 1
- Provider container loses data in widget test HOT 4
- AutoDisposeNotifierProvider causing state loss HOT 3
- Reword `The ref.watch method should not be called asynchronously`
- Add a DevTools extension for riverpod HOT 2
- Broken update HOT 3
- [riverpod 3] NotifierProvider doesn't work with a NotifierBase mixin.
- riverpod_generator does not respect import aliases HOT 1
- Ref onError callback HOT 1
- `ref.exists()` returns `true` when manually invalidate a provider.
- `yarn dev -l {LANG}` is needed when hosting documentation website locally for specific locale with docusaurus
- Stream from StreamProvider is not unsubscribed to when widgets get disposed
- There is no way to handle the "done" event on the stream of a StreamProvider
- `ref.invalidate(familyProvider)` is not working with scoped providers
- PageController stateprovider doesn't work when .previousPage() or nextPage() is pressed HOT 1
- beforeDispose or beforeInvalidate hook, happen before invalidate HOT 6
- Multiple invalidation of Providers HOT 2
- Unable to use the latest riverpod in flutter version lower than 3.16 HOT 2
- The getter 'variable2' isn't defined for the class 'PropertyAccessorElement'. HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from riverpod.