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

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(),
);
}
}

Related

Flutter Provider integer Reset

I have a count variable like this:
class Count with ChangeNotifier {
int _count = 1;
int get count => _count;
void setCount(bool isIncrement) {
if (isIncrement) {
_count = checkCount(_count + 1);
} else {
_count = checkCount(_count - 1);
print("decrement" + _count.toString());
}
notifyListeners();
}
int checkCount(int count) {
if (count < 0) {
return 0;
} else if (count > 10) {
return 10;
} else {
return count;
}
}
}
I'm using the provider to use it on the food pages. But when I switch between the pages, the count variable continues from where it left off. I want it to restart as 1 every time the page changes.
class Hamburger extends StatefulWidget {
const Hamburger({super.key, required Count count});
#override
State<Hamburger> createState() => _HamburgerState();
}
class _HamburgerState extends State<Hamburger> {
#override
Widget build(BuildContext context) {
Color coloricon = Provider.of<iconcolor>(context).coloricon;
int count = Provider.of<Count>(context).count;
return Scaffold(
…
);
}
}
The idea of Provider is to have a consistent state across all your pages.
If you want to save only the number of hamburgers selected you need a variable similar to _hamburgerCount and control it there.
Or, for a more scalable solution, you can create a Map<String, int> or something similar to store the amount of each type. There is many ways to solve this, but with one global count variable you can not achieve storing a count for each type of food.

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

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();
}
}

Dart Analysis Detects and Unused Field...what am I missing?

As you can see from my code sample, I'm using this variable. I also reference multiple times later in the class.
Flutter Warning - info: The value of the field '_loadTimer' isn't used. (unused_field at [app] lib/models/knowledge_level/pb_cycle_permissions_collection.dart:12)
ng is: info: The value of the field '_loadTimer' isn't used. (unused_field at [app] lib/models/knowledge_level/pb_cycle_permissions_collection.dart:12)
import 'dart:async';
import 'dart:collection';
import 'package:app/data/graphql/queries.dart';
import 'package:app/helpers/shared_logger.dart';
import 'package:flutter/cupertino.dart';
import '../command_permission.dart';
class PBCyclePermissionsCollection
with ListMixin<CommandPermission>, ChangeNotifier {
Timer? _loadTimer;
///
/// CONSTRUCTION AND INITIALIZATION
///
static final PBCyclePermissionsCollection _instance =
PBCyclePermissionsCollection._internal();
factory PBCyclePermissionsCollection() {
return _instance;
}
/// ACCESS SINGLETON VIA myPBCyclePermInstance = PBCyclePermissionsCollection()
PBCyclePermissionsCollection._internal() {
_loadTimer = Timer(_waitFirstLoad, _attemptLoad);
}
///
/// PRIVATE VARIABLES AND METHODS
///
static final Duration _waitFirstLoad = Duration(milliseconds: 500);
static final Duration _waitRetryLoad = Duration(seconds: 2);
static final int _maxAttempts = 4;
int _loadAttempts = 0;
bool _isReady = false;
bool _hasFailed = false;
/// Storage of CommandPermissions List once loaded
final List<CommandPermission> _list = [];
void _attemptLoad() async {
_loadAttempts++;
SharedLogger.I().d('_attemptLoad() current load attempt: ${_loadAttempts}');
try {
final results = await Queries.getCommandPermissions();
var data = results.data!['commandPermissions'];
var permissions = <CommandPermission>[];
for (var item in data) {
permissions.add(CommandPermission.fromJson(item));
}
/// Populated class with loaded objects.
_list.clear();
_list.addAll(permissions);
_isReady = true;
notifyListeners();
} catch (e) {
SharedLogger.I().e('Error loading PBCycle Permissions - ${e}');
_newAttempt();
}
}
void _newAttempt() {
SharedLogger.I().d(
'_newTry() _loadAttempts: ${_loadAttempts} _maxAttempts:${_maxAttempts} '
'creating new loadTimer for another try? : ${!(_loadAttempts >= _maxAttempts)}');
if (_loadAttempts >= _maxAttempts) {
_hasFailed = true;
notifyListeners();
// TODO: do we invalidate any existing data that may have been loaded before? Like if this load cycle is a refresh?
// If so, we should reset _isReady and _list;
return;
}
_loadTimer = Timer(_waitRetryLoad, _attemptLoad);
}
///
/// PUBLIC METHODS
///
bool get isLoaded {
return _isReady;
}
bool get hasFailed {
return _hasFailed;
}
#override
set length(int newLength) {
throw ('length cannot be changed externally');
}
#override
int get length {
return _list.length;
}
#override
CommandPermission operator [](int index) {
return _list[index];
}
#override
void operator []=(int index, CommandPermission value) {
throw ('Cannot modify list from outside');
}
}
Image of IDE with Code Sample and associated Dart Analysis Hints
You aren't actually using it, you're just setting the value multiple times
The answer from Andrew is correct, but a bit unclear since unsure what 'it' refers to. Here's another way to explain what the warning message means:
Notice that the message says you are not using the value. You are using the variable, but not its value. You are assigning the value. To read the value would be using it.
That said, the question is answered, but I think the question is somewhat vague by asking "what am i missing". What do you (OP) want to achieve? I assume it's to not see that warning anymore. And that is what brings me to this post. I have similar issue. I too have a class variable for a Timer and I get this same warning message. One does not need to read the value in order to use a timer but the analyzer doesn't know that. While writing this response I have discovered that you can a suppress warning. How about this:
// ignore: unused_field
Timer? _loadTimer;

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);
}
}

how to display random number in flutter

I need to display a random number in flutter using a function, but when i call it i get error.
void generateRandomNumber() {
setState(() {
point=pointValue[new Random().nextInt(pointValue.length)];
});
}
Return int value from your method which generated by Random class
List<int> pointValue = [5,6,7,8,10,15];
int generateRandomNumber() {
return pointValue[new Random().nextInt(pointValue.length)];
}