Flutter Search bar not refreshing the initial list - flutter

i'm having a little trouble in getting back the initial list in my app, after searching an item.
I have a list car and i'm using code from tutorials, if i let the text in the formfield and change tabs, when i back the filter continues and the bar is empty.
I already tried 100 forms and keeps getting the same result.
Here's parts of the code.
List<Car> car = cars;
final _pesquisaController = TextEditingController();
I have a default textformfield with this controller above and a onchange calling the method below.
void pesquisarCarro(String query) {
var carrosPesquisados = {
...car.where(
(cars) {
var nomedoCarro = cars.nomeCarro.toLowerCase();
var input = query.toLowerCase();
return nomedoCarro.contains(input);
},
),
...car.where(
(cars) {
var codigodoCarro = cars.codigo.toLowerCase();
var input = query.toLowerCase();
return codigodoCarro.contains(input);
},
)
}.toList();
setState(
() {
cars = carrosPesquisados;
},
);
}
Already tried putting the list on the initState but not work, can someone give me a light?
Like said, the search filters perfectly, the problem is when i let text in the form and change tabs in the bottomtabbar.

is your problem is initial value always empty?
#override
void initState() {
onInit();
super.initState();
WidgetsBinding.instance.addPostFrameCallback((callback) {
// set your list here
});
}

Related

Code after "await" is not executing properly in flutter

I am trying to read data from a Firebase real time database and use it in a bar graph.
My code starts off by simply reading the data from the DB (specifically the item names), and then storing them in a list (itemNames). This is all done in the activateListeners() method.
From this point, I call the activateListners() method in the generateData() method, in order to start using the data in the itemNames list for the bar chart. Since the activateListeners() method is asynchronous, I use the "await" keyword to ensure that the item names are stored in the list before moving on.
After this point, I plan on creating ProductSales objects with the name of each item from the database, as well as the quantity. This will be done by getting the item names from the itemNames list.
However, before I do this, I was testing to see if the bar chart would work normally with test data.
The issue is that when I run the code, the bar chart does not display, as it seems to not be reading in the data. HOWEVER, if I remove the "await activateListners()" from the generateData() method, the bar chart displays the test data perfectly.
Why is the ber chart not displaying the data when I await for the activateListeners() method to execute first?
Any help would be much appreciated!
class _ProductBarChartState extends State<ProductBarChart> {
//Ref to DB
final DatabaseReference _dbRef = FirebaseDatabase.instance.ref();
late DataSnapshot _itemStream;
//Stores the description of each menu item in the DB
String itemName = "";
String itemID = "";
List<String> itemNames = [];
List<String> itemIDs = [];
//Reads the item names from the DB and adds them to a list
Future _activateListeners() async {
for (int i = 1; i <= 10; i++) {
itemID = "J$i";
_itemStream = await _dbRef.child("menuItem/$itemID/itemName").get();
itemName = _itemStream.value.toString();
itemNames.addAll([itemName]);
}
}
List<charts.Series<ProductSales, String>> _seriesBarData =
[]; //A list that will store all the sales data for the bar chart report
_generateData() async {
await _activateListeners();
var BarChartData = [
//Stores all ProductSales objects for the product report
ProductSales("Hake", 8),
ProductSales("Toasted", 15),
ProductSales("Chick strips", 28),
ProductSales("Kota", 40),
];
//Adding the BarChartData (seen above) to the list
_seriesBarData.add(charts.Series(
id: 'SalesPerProduct',
colorFn: (_, __) =>
charts.ColorUtil.fromDartColor(Color.fromARGB(255, 255, 157, 38)),
domainFn: (ProductSales productSales, _) => productSales.productName,
measureFn: (ProductSales productSales, _) => productSales.noOfProductSold,
data: BarChartData,
));
}
#override
void initState() {
// TODO: implement initState
super
.initState(); //This runs the original initState function that we inherited from the material app class (even though we override i)
_seriesBarData = <charts.Series<ProductSales, String>>[];
_generateData(); //Generates all the data for the chart (method specified above)
}
Call setState to update the UI end of _generateData
_generateData() async {
//...
setState((){}) ;
}

In Getx Flutter how can I get result from function?

I would like to get a percent making two functions.
My first function is a filtered list of my data.
int countP(String idC) {
final _ps = ps.where((element) => element.idC == idC);
return _ps.length;}
My second function comes from my first function:
int countPP(String idC) {
final _ps = ps.where((element) => element.idC == idC);
final _psPd = _ps.where((element) => element.pd != '');
return _psPd.length;}
In my view I would like to show the percent:
final percentPd =((pCtrl.countPP(idC) * 100) / pCtrl.countP(idC)).round();
I need to show the result in Text:
Text(percentPd)
My question is:
How can I show the result in Text Widget using Getx, because when I open my view the first time doesn't show the result, but if I refresh, yes?
I used Obx, GetX, and GetBuilder in my Text.
I put my controller using Get.find() but doesn't work.
I Used Get.put(Controller) and doesn't work
You should declare percentPd like this
final percentPd = 0.obs;
percentPd.value = ((pCtrl.countPP(idC) * 100) / pCtrl.countP(idC)).round();
and then assign it's value afterwards and use Obx on the widget where you want to show it.
In your widget use this code :
#override
Widget build(BuildContext context) {
return {
GetBuilder<yourController>(builder: (controller)
{
return Text(controller.percentPd)
}
}

Flutter Function to reload variable

I wanted to make like a currency converter so I created this,
final montant = TextEditingController()..text = '500';
double convertEuro(montant) {
double convtEur = (double.parse(montant.text) / 3.2);
return convtEur;
}
double converted = 0;
I had a problem with my function here because the function when the screen loads it's null so I created that converted variable ( It's a stupid move I know at least to get rid of the error on my screen but only showing the initial value from my textController above
Text(
"${double.parse(montant.text)}" +
"DT = $converted" +
" €",
)
Anyway, the function is triggered when a button is pressed.
onPressed: () {
if (_formKey.currentState.validate()) {
converted = convertEuro(montant);
}
},
Can anyone help me how to change that variable value and make it change on my screen when the button is pressed?
You can do like this:
setState(() {
converted = convertEuro(montant);
});
In this, you're basically doing a rebuild of the widget.
Thus to implement this in your code, put setState under the onPress:
onPressed: () {
if (_formKey.currentState.validate()) {
setState(() {
converted = convertEuro(montant);
});
}
},

Firebase querying one time and listen in entire app?

I have an app which is basicly 4 pages and I am using firebase real-time db for favorites, first page show general random items and get's all user info from db with a query and make a list then listen for changes, I am using this list to check items are added or not, second page is a list page and doing same thing actually, third page is related persons and doing same thing, only my detail page request with id of item with user id instead of whole user data then check it. I just wonder it is possible to make query and custom list only one time instead of querying in every page then listen change if something added or change? Or my approach is a right way? A user information could be a bit large according to user, maybe around 2000 item id childs under single user id child and every id childs has 15 data lines. You can see my structure below.
Query part of code(It is almost same for every page):
#override
void initState() {
super.initState();
_moviesList = new List();
_moviesQuery = _database
.reference()
.child("movies").child(widget.userId)
.orderByChild("userId")
.equalTo(widget.userId);
_onMoviesAddedSubscription = _moviesQuery.onChildAdded.listen(onEntryAdded);
_onMoviesChangedSubscription =
_moviesQuery.onChildChanged.listen(onEntryChanged);
widget.auth.getCurrentUser().then((user) {
setState(() {
if (user != null) {
userId = user?.uid;
}
authStatus =
user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
});
});
}
void dispose() {
_onMoviesAddedSubscription.cancel();
_onMoviesChangedSubscription.cancel();
super.dispose();
}
onEntryChanged(Event event) {
var oldEntry = _moviesList.singleWhere((entry) {
return entry.id.toString() == event.snapshot.key;
});
setState(() {
_moviesList[_moviesList.indexOf(oldEntry)] =
Movies.fromSnapshot(event.snapshot);
});
}
onEntryAdded(Event event) {
setState(() {
_moviesList.add(Movies.fromSnapshot(event.snapshot));
});
}

Flutter: remove duplicated items when filtering ListView

I'm working on ListView filtering like this.
Le't say you type tsi. Then the result is:
which is correct. And if you clear the search input box, the default/original list should be displayed. Instead, there will be duplicated items. Weird.
Here's the filtering code:
onSearchTextChanged(String input) async {
List<ParkingItem> dummySearchList = List<ParkingItem>();
dummySearchList.addAll(_parkingList);
if (input.isNotEmpty){
List<ParkingItem> dummy = List<ParkingItem>();
dummySearchList.forEach((item){
if (item.location.toLowerCase().contains(input.toLowerCase())){
dummy.add(item);
}
});
setState((){
_parkingList.clear();
_parkingList.addAll(dummy);
});
return;
}
else {
setState(() {
_parkingList.clear();
_parkingList.addAll(backup);
});
}
}
And this is the full code. What's wrong here?
Using that dummySearchList and the other dummy list, seems a bit confusing to me. I would suggest having two lists in the state of your widget. One containing all the items, basically the source of your ParkingItems, and one for the items you want to display.
I've typed this out a bit in dartpad, hopefully this might help you.
List<ParkingItem> _allItems;
List<ParkingItem> _displayedItems;
#override
initState() {
super.initState();
_allItems = []; // TODO: fetch all items first
_displayedItems = _allItems; // initially, display all items
}
onSearchTextChanged(String input) async {
if(input.isNotEmpty) {
setState(() {
// set displayed items as a filtered set of allItems, by using `where`
_displayedItems = _allItems
.where((ParkingItem item) => item.location.toLowerCase().contains(input.toLowerCase()))
.toList(); // turn the Iterable back into a List
});
} else {
setState(() {
// no search field input, display all items
_displayedItems = _allItems;
});
}
}