How to display only special parts in a list FLUTTER - flutter

I'm very new to flutter and I wondered how I can make something like that:
I want loop trough a List of Items and make a Widget for all of them. I do this with a for-block instead of a listView.builder, because so it isn't a list. But I want to display for example every Item which has "valid" as value for worth in a different block as them, which has "invalid" as value.
I thought I could do this like that:
Text("Valid"),
for (ValuePair item in items)
if (item.worth == "valid"){
return myOwnView(item);
},
Text("Invalid"),
for (ValuePair item in items)
if (item.worth == "invalid"){
return myOwnView(item);
};
What could I do instead of that?

First solution (preferable):
I would filter the values in the list first, than pass it to your own builder like that:
List<YourItemClass> yourUnsortedList = [...];
List<YourItemClass> yourSortedList = [...];
for (var I = 0; I < yourUnsortedList.length; i++) {
if (yourUnsortedList.worth == 'valid') {
yourSortedList.add(yourUnsortedList[i])
}
}
next - just build this list.
Second solution (bad one):
Inside your builder place if statement on top, and if you need nothing to be built, return empty container, like that:
List<YourItemClass> yourUnsortedList = [...];
Listview.builder(
itemCount: yourUnsortedList.length;
itemBuilder: (context, idx) {
if (yourUnsortedList[idx].worth == 'valid') {
return YourOwnItem(item);
} else {
return Container();
}
}
)

Try making two lists of type Widget, one for valid and the other for invalid.
So, we have:
List<Widget> validChildren = List.empty(growable=true);
List<Widget> invalidChildren = List.empty(growable=true);
then use for loop to add the children:
for(Valuepair item in items)
if(item.worth == "valid")
validChildren.add(MyOwnView(item));
else
invalidChildren.add(MyOwnView(item));
you can add these lists as children of a column or a row.
You can give continue; in place of invalidChildren.add() if you don't want that list.

Related

How to handle lists initial building in Getx

I'm making a reactive model with Getx on a product list, but when I start the list it comes with no value and causes an index error even though there are actually values ​​in the list it appears empty at first, which somehow gets fixed automatically. (this is inside a build of a statelesswidget)
return GetX<CartController>(
init: CartController(),
builder: (controller) {
try {
return Text(
"${StringConvert.toMoney(controller.totalByProduct[productId])}",
style: kSmallTextBold,
);
} catch (e) {
return const Text("Error...");
}
},
);
}
I did try catch to manage this, but the catch part doesn't show up;
this is relevant part of the controller
var totalByProduct = [].obs;
fetchTotal() {
List products = storage.read(StorageKeys.cartProducts);
double currentValue = 0.0;
List currentTotals = [];
for (var item in products) {
currentTotals.add(item['total'] * item['amount']);
currentValue += item['total'] * item['amount'];
}
total.value = currentValue;
totalByProduct.value = currentTotals;
}
I believe it's not the right way to do this, so what do I need to know to fix this correctly?
If helps this is the error:
With a method to read the storage (sharedPreferences) in async mode, with a FutureBuilder it was possible to correct the error, because in the initial state the list takes the value assigned explicitly. Even if it then receives the correct value, accessing the index in its initial state causes the error, this explains why even with the error it works.

value of my List is changing when i delete text from TextField Flutter

i have a list that i want to search in (I remove the values that don't match my search), I write the search word in a TextField and save the initial list in order to show it again when the user deletes the search word (or want to search for another thing) .
i can save the list in a variable but the issue is when I start deleting the search word the value of my initial list becomes the same that the list I show for the search !
onChanged: (val) {
//i save the list before doing any change here
if (_initList == null) _initList = myList;
// this part works fine
if (val.length > 2)
setState(() {
myList.removeWhere((element) => !element
.getName()
.toLowerCase()
.contains(val.toLowerCase()));
});
// when i’m in the else, when i try to print _initList value i find that it’s the same as myList
// the value of _initList is not changing anywhere else in the code
else {
setState(() {
myList = _initList;
});
}
},
when you do this
if (_initList == null) _initList = myList;
both variables will point to the same list. changes to one list will also change the other, because they are in fact the same list. What you want to do is safe a copy of the list in it. You can do it by calling toList() on it, like
if (_initList == null) _initList = myList.toList();

How to increment counter for a specific list item in Flutter using Getx?

Like in my sample image, below, I want to increment or decrement quantity upon button click for single list item.
image link
any idea?
##solution: ##
addProduct(ProductModel product) {
var existing = products.indexWhere((p) => p.barcode == product.barcode);
if (existing != -1) {
product.quantity = products[existing].quantity + 1;
products[existing] = product; // instead of products[existing].quantity ++;
} else {
print('adding');
products.add(product);
}
}
solution from github
You must copy the list you have, access the item, modify it and pass the new modified list to your GetX class.

Adding and Removing Items From Flutter Lists Dynamically

I have these two functions that should add the item onTap to the list, and then another one to delete the item. The first one (adding the item) works fine, but the delete one doesn't seem to delete anything. I suspect the issue is that the counter variable is not global, but for some reason it doesn't work fine when I add it globally (and I would need it to be). Here's the full code:
List<int> _totalPrice = [];
List<int> get totalPrice => _totalPrice;
here is the add item function
Future getTotal(item) async {
int counter = 0;
_totalPrice.add(int.parse(item));
_totalPrice.forEach((element) => counter += element);
print('LIST: $_totalPrice');
print('SUM: $counter');
return counter;
}
here is the delete function that doesn't remove anything
deleteSumItem(String item) {
_totalPrice.remove(item);
}
I think the issue is that the counter variable isn't global, I am not sure how to add it globally to change dynamically.
So, here your code shows that you are putting int in your _totalPrice list, but you are trying to remove the String from the list. It will not be found to be deleted.
So, you can change the data type of your list into String or you can write the below function to delete an item where the function only takes an int
deleteSumItem(int item) {
_totalPrice.remove(item);
}
Also you can remove an item by below line of code (If you have a custom type of data in your list):
_totalPrice.removeWhere((item) => item.price == '520')

How to exclude ElementArrayFinder items that exists in another ElementArrayFinder in Protractor?

I would like to obtain menu-ui items that user is able to click.
Unfortunately, isEnabled method returns always true for all of my items.
That's why I try another approach. I noticed that disabled ones, always have 'ui-state-disabled' class. As a consequence, I'm able to get all disabled items, using following function:
function getDisabledMenuItems() {
return getCustomGrid().all(by.className('menu-ui')).all(by.className('ui-state-disabled')).all(by.className('menu-item-text'));
}
and then all menu items using following one:
function getAllMenuItems() {
return getCustomGrid().all(by.className('menu-ui')).all(by.className('menu-item-text'));
}
Now I would like to exclude items returned by getDisabledMenuItems from items returned by getAllMenuItems.
Question
What is the easiest way to exclude ElementArrayFinder items that exists in another ElementArrayFinder?
I'm trying to do that by means of filter method as follows:
const disabledText = getDisabledMenuItems().getText();
const allItems = getAllMenuItems();
allItems.filter(function(elem, index) {
return elem.getText().then(function(text) {
return disabledText.indexOf(text) < 0 ;
});
});
but my code does not work (indexOf does not exists on type Promise<string>).
I also wonder what is the easiest way to do that.
Because getDisabledMenuItems().getText() return a promise, you have to consume its eventual value in then():
const disabledText = getDisabledMenuItems().getText();
const allItems = getAllMenuItems();
const enableItems = allItems.filter(function(elem, index) {
return elem.getText().then(function(text) {
return disabledText.then(function(txts){
return txts.includes(text) === false;
// or use return txts.indexOf(text) < 0;
});
});
});