How to copy a list into another in a StateNotifier, so it update with every change - flutter

The List EleccionSinSeleccionClase is just a list of a class who has a String on it.
class EleccionSinSeleccionClase {
String Eleccion;
}
The state List is another class:
class EleccionConSleccionClase {
String Eleccion;
bool selec;
}
The problem is that I want to copy the first into the state of the StateNotifier, this line break the code.
This is the line: state[i].Eleccion = ListaElecciones[i].Eleccion;
class EleccionesConSeleccionNotifier
extends StateNotifier<List<EleccionConSleccionClase>> {
final List<EleccionSinSeleccionClase> ListaElecciones;
EleccionesConSeleccionNotifier({required this.ListaElecciones}) : super([]);
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}
}
}
}
final eleccionConSleccionStateNotifierProvider = StateNotifierProvider<
EleccionesConSeleccionNotifier, List<EleccionConSleccionClase>>((ref) {
final eleccioneswatch =
ref.watch(eleccionesSinSeleccionStateNotifierProvider);
return EleccionesConSeleccionNotifier(ListaElecciones: eleccioneswatch)..init();
});

Maybe the problem is that you initialize state as an empty list super([]) and then you're trying to change a value in an index that doesn't exist (state[i] where the list is obviously empty and cannot access that position)
void init(){
print(ListaElecciones.length.toString());
if(ListaElecciones.length != 0){
/// you will need to check if both lists are the same lenght if you actually want to do this
/// without failling
/*for (int i = 0; i < ListaElecciones.length; i++) {
state[i].Eleccion = ListaElecciones[i].Eleccion; ////HERE////
}*/
/// if you only want to copy Eleccion parameter in a new class this would be the easiest way
state = ListaElecciones.map((cb) => EleccionConSleccionClase(Eleccion: cb.Eleccion)).toList();
}
}

Related

Cannot convert Datatypes from-to

I have a class called DisplayInventory
Dictionary<InventoryObject, GameObject> itemsDisplayed = new
Dictionary<InventoryObject, GameObject>();
itemsDisplayed.Add(inventory.Container[i], obj);
the code breaks at this line (inventory.Container[i]) because it
cannot convert (field) List InventoryObject.Container.
this is my InventoryObject class
public class InventoryObject : ScriptableObject {
public List Container = new List();
public void AddItem(ItemObjectData _item, int _amount)
{
bool hasItem = false;
for (int i = 0; i < Container.Count; i++)
{
if(Container[i].item == _item)
{
Container[i].AddAmount(_amount);
hasItem = true;
break;
}
}
if(!hasItem)
{
Container.Add(new InventorySlot(_item, _amount));
}
}
}
[System.Serializable] public class InventorySlot {
public ItemObjectData item;
public int amount;
public InventorySlot(ItemObjectData _item, int _amount)
{
item = _item;
amount = _amount;
}
public void AddAmount(int value)
{
amount += value;
} }
The part where you declare the inventory variable or specifically inventory.container is missing.
Or is this the container from the InventoryObject class?
You need the specific type InventoryObject for the Dictionary.
What you are giving into it is simply just a List object that you put inside the container.
If you are refering to the container from the InventoryObject class, it really is just a List() that you hold there.
In this case the Dictionary would only need inventory as input.
Or you could change from
public List Container = new List();
to this
public List<InventoryObject> Container = new List<InventoryObject>();
This would still make more sense if this container is outside of the InventoryObject and in an Inventory class or something.

Why can't I set a dynamic property inside a nested function?

I'm trying to create a function that can dynamically set the properties on an object like so:
void main() {
final obj = Item();
obj.update(5);
print(obj.xVal);
}
class ObjectBase {
void _setData(current, newValue) {
current = newValue;
print(current);
}
}
class Item extends ObjectBase {
int _x;
int get xVal => _x;
update(x) {
_setData(_x, x);
}
}
The print statement in _setData works fine, but it doesn't actually appear to change _x, even if it has been passed through. I expected that changing the reference here would update it everywhere.
So why isn't this working and is there a fix?
You can assume that I do have good reason to be calling _setData inside update rather than just implementing the functionality in update.
Update:
A real life example of what i'm trying to achieve
class ViewModel extends ChangeNotifier {
void _setDataFromDependency(current, newValue) {
if (!deepDynamicEquality(current, newValue)) {
current = newValue;
notifyListeners();
}
}
}
class ListScreenViewModel extends ViewModel {
int _localCount = 0;
List<int> _globalList;
ListScreenViewModel();
List<int> get globalList => _globalList;
int get localCount => _localCount;
incrementLocal() {
_localCount++;
notifyListeners();
}
void update(ListStore listStore) {
_setDataFromDependency(_globalList, listStore.globalList);
// if (!deepDynamicEquality(_globalList, listStore.globalList)) {
// _globalList = listStore.globalList;
// notifyListeners();
// }
}
}
An oversimplified workaround is to return the value from _setData . #julemand101 has already answered limitations.
class ObjectBase {
int _setData(current, newValue) {
current = newValue;
print('current: $current');
return current;
}
}
class Item extends ObjectBase {
int _x;
int get xVal => _x;
update(x) {
_x = _setData(_x, x);
}
}

Using List to store and find class element with random member variable

I want to store a class in a List to later retrieve the value. Now the problem I
m having is that one of the members is a random value. So when trying to retrieve the entry I can't find it, since I can't produce the 'key'.
I'm happy for suggestions on implementing this in a different way.
So this is the example class I want to store in a list:
class MyDevice{
int device;
int randomNumber;
void set(int device, int random){
this.device = device;
this.randomNumber = random;
}
}
class Handling{
final List<MyDevice> myDevicesList = new List<MyDevice>();
...
...
MyDevice dev = new MyDevice();
dev.set(device, random);
//Store entry into List
myDevicesList.add(dev);
...
...
Now I want to delete or possibly replace an entry, but I will have no way of
finding it since the random value is not known after storing above.
// Note that I have the device value supplied in a call-back, for the sake of this
// example let's just define a method for removing
void removeEntry(int device){
MyDevice dev = new MyDevice();
dev.set(device, );
myDevicesList.remove(dev);
}
How can I find / remove an entry that is a class and I only want to 'search' the list with one of the embers in the class that is stored?
Is the only solution to walk the list and make my own compare method to identify the entry by the 'device' member?
All you need is the removeWhere List method. You have to remove where MyDevice.device matches the argument, device.
Here's the code you requested for
void removeEntry(device) {
myDevicesList.removeWhere((element) => element.device == device);
}
Here's the full code.
import 'dart:math';
class MyDevice {
int device;
int randomNumber;
void setValue(int device, int random) {
this.device = device;
this.randomNumber = random;
}
}
class Handling {
final List<MyDevice> myDevicesList = new List<MyDevice>();
void addToList(device, random) {
MyDevice dev = new MyDevice();
dev.setValue(device, random);
myDevicesList.add(dev);
}
void removeEntry(device) {
myDevicesList.removeWhere((element) => element.device == device);
}
List<MyDevice> get list {
return myDevicesList;
}
}
void main() {
final handle = new Handling();
handle.addToList(2, Random().nextInt(5));
handle.addToList(18, Random().nextInt(4));
handle.addToList(12, Random().nextInt(9));
print("List before ${handle.list.map((element) {
return [element.device, element.randomNumber];
})}");
handle.removeEntry(18);
print("List after ${handle.list.map((element) {
return [element.device, element.randomNumber];
})}");
}
The output is
List before ([2, 1], [18, 0], [12, 7])
List after ([2, 1], [12, 7])
Here's the solution on dartpad
You don't know random value, so you have to manually compare and remove item from list.
Following code may help you.
In following example i added 1,2 and 5 and remove 2 after that you can see in print only 1 and 5.
class MyDevice {
int device;
int randomNumber;
void set(int device, int random) {
this.device = device;
this.randomNumber = random;
}
}
class Delet2 extends StatefulWidget {
#override
_Delet2State createState() => _Delet2State();
}
class _Delet2State extends State<Delet2> {
final List<MyDevice> myDevicesList = new List<MyDevice>();
#override
void initState() {
super.initState();
add(1);
add(2);
add(5);
delete(2);
for (int k = 0; k < myDevicesList.length; k++) {
print(myDevicesList[k].device);
}
}
add(int number) {
MyDevice dev = new MyDevice();
dev.set(number, Random().nextInt(1000));
myDevicesList.add(dev);
}
delete(int number) {
for (int i = 0; i < myDevicesList.length; i++) {
if (myDevicesList[i].device == number) {
myDevicesList.removeAt(i);
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}

How can I combine multiple objects based on the same value they have in Dart?

class Item{
var name;
var productId;
Item(this.name,this.productId);
}
class Price{
List<String> listOfProductIds = [];
double amount;
}
Lets say I have list of prices:
[["productid1","productid3"], 199.00], ["productid2","productid4"],299.00],...);
I have TWO different lists.
This one:
[["myName","productid1"],["myNamee","productid2"]]
And, this one:
[["myName","productid3"],["myNamee","productid4"]]
for example, I want to retrieve items for a price of 199.00. basically I want to show ["myName","productid1"] and ["myName","productid3"] How can I achieve this?
As far as I know this is a custom use case and this cannot be done with a single statement in Dart. However, this result can be achieved with the help of the forEach loop in Dart.
Here is a minimal example reproducing your above problem -
class Prices {
List<String> products;
double price;
Prices(this.products, this.price);
}
void main() {
List<Prices> priceList = [Prices(["productid1","productid3"], 199.00), Prices(["productid2","productid4"],299.00)];
List<List<String>> productList1 = [["myName","productid1"],["myNamee","productid2"]];
List<List<String>> productList2 = [["myName","productid3"],["myNamee","productid4"]];
List<List<String>> resultList = List();
List<String> comparatorList = priceList.singleWhere((priceObj) => priceObj.price == 199.0).products;
productList1.forEach((product) {
if(comparatorList.contains(product[1])) {
resultList.add(product);
}
});
productList2.forEach((product) {
if(comparatorList.contains(product[1])) {
resultList.add(product);
}
});
print(resultList.toString());
//Above statement prints [[myName, productid1], [myName, productid3]]
}
In the above example first we create the comparatorList which contains the names of only those products which are priced at 199.0.
Then, we extract only those items from both the product lists which are present in the comparatorList as well. Hope this helps!
This is what I have done to overcome the issue:
Item tempOne,tempTwo;
for(int i=0; i<prices.listOfProductIds.length;i++){
for(int j=0; j<itemOne.length; j++){
if((prices.listOfProductIds[i]) == (itemOne.productId)){
tempOne = itemOne;
break;
}
}
for(int j=0; j<itemTwo.length; j++){
if((prices.listOfProductIds[i]) == (itemTwo.productId)){
tempTwo = itemTwo;
break;
}
}
Wrapper finalResult = new Wrapper(tempOne,tempTwo,prices[i]);
}
Defined wrapper class
class Wrapper{
Item itemOne,itemTwo;
Price price
Warpper(this.itemOne,this.itemTwo,this.price)
}

Plugin dev: How to search only for interfaces in DLTK/PDT plugin?

I develop extension of PDT plugin. I need dialog with interfaces only (not classes). Basic code looks like it:
OpenTypeSelectionDialog2 dialog = new OpenTypeSelectionDialog2(
DLTKUIPlugin.getActiveWorkbenchShell(),
multi,
PlatformUI.getWorkbench().getProgressService(),
null,
type,
PHPUILanguageToolkit.getInstance());
It's works fine but I get classes and interfaces together (type variables). Is any method to filter it? I can't find this kind of mechanism in PDT but classes and interfaces are recognize correctly (icons next to names).
I don't know if its the best solution but it works.
int falseFlags = 0;
int trueFlags = 0;
IDLTKSearchScope scope = SearchEngine.createSearchScope(getScriptFolder().getScriptProject());
trueFlags = PHPFlags.AccInterface;
OpenTypeSelectionDialog2 dialog = new OpenTypeSelectionDialog2(
DLTKUIPlugin.getActiveWorkbenchShell(),
multi,
PlatformUI.getWorkbench().getProgressService(),
scope,
IDLTKSearchConstants.TYPE,
new PHPTypeSelectionExtension(trueFlags, falseFlags),
PHPUILanguageToolkit.getInstance());
And PHPTypeSelectionExtension looks like this:
public class PHPTypeSelectionExtension extends TypeSelectionExtension {
/**
* #see PHPFlags
*/
private int trueFlags = 0;
private int falseFlags = 0;
public PHPTypeSelectionExtension() {
}
public PHPTypeSelectionExtension(int trueFlags, int falseFlags) {
super();
this.trueFlags = trueFlags;
this.falseFlags = falseFlags;
}
#Override
public ITypeInfoFilterExtension getFilterExtension() {
return new ITypeInfoFilterExtension() {
#Override
public boolean select(ITypeInfoRequestor typeInfoRequestor) {
if (falseFlags != 0 && (falseFlags & typeInfoRequestor.getModifiers()) != 0) {
// Try to filter by black list.
return false;
} else if (trueFlags == 0 || (trueFlags & typeInfoRequestor.getModifiers()) != 0) {
// Try to filter by white list, if trueFlags == 0 this is fine 'couse we pass black list.
return true;
} else {
// Rest is filter out.
return false;
}
}
};
}
#SuppressWarnings("restriction")
#Override
public ISelectionStatusValidator getSelectionValidator() {
return new TypedElementSelectionValidator(new Class[] {IType.class, INamespace.class}, false);
}
}