flutter\: Unhandled Exception: Concurrent modification during iteration: _LinkedHashMap len:0 - dictionary

i get this error when i try to remove something from my purchasedItems map which is pf type <String,dynamic>, anyone know why?
for (var key2 in purchasedItems.keys) {
for (var id in currentIds) {
if (key2 != id) {
print("key is $key2");
purchasedItems.removeWhere((key, value) => key == key2);
}
}
}

This error means that you are adding or removing objects from a collection during iteration. This is not allowed since adding or removing items will change the collection size and mess up subsequent iteration.
So you cant remove an item in a loop, instead yo can create a list of objects that must be removed and after the loop remove them. Something like this:
var toRemove = [];
for (var key2 in purchasedItems.keys) {
for (var id in currentIds) {
if (key2 != id) {
print("key is $key2");
toRemove.add(key)
}
}
}
purchasedItems.removeWhere( (e) => toRemove.contains(e));

Related

Issue with deleting a list item

issue:
List<string> list = new List<string>();
list.Add("a");
list.Add("b");
list.Add("c");
foreach (var item in list)
{
if (item == "a")
{
list.Add("af");
}
}
Above is my code when i am trying to add item to list it is giving exception "Collection was modified; enumeration operation may not execute". Can anybody help on this why i am getting this exception.
You can't modify the list while you are iterationg over it.
But you can create another list and work on it:
List<string> list = new List<string>();
list.Add("a");
list.Add("b");
list.Add("c");
List<string> tmpList = new List<string>(list);
foreach (var item in list)
{
if (item == "a")
{
tmpList.Add("af");
}
}
list = tmpList;
You can't modify the iterated collection from inside a foreach loop. This is what the error message is telling you. Since you're working with a list, you can just use a for loop instead.
for(int i = 0; i < list.Count; i++)
{
if (list[i] == "a")
{
list.Add("af");
}
}
Here's the relevant documentation that explains what you're seeing:
An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException.

Get Meteor collection object instance by name

I have seen similar questions but I think my scenario is a bit different. Say I define a collection like this:
MyCol = new Meteor.Collection("myCol"
and I want to get a reference to 'MyCol' using the string 'myCol' - I have created the function below which seems to work:
function GetCollectionObject(name) {
for(var key in window) {
var value = window[key];
if (value instanceof Meteor.Collection) {
if (value._name == name) {
return value;
break;
}
}
}
return null;
}
Is this the only/best/most efficient way to do this?
Why don't you store your collections in a dictionary? It's way more efficient.
Dogs = new Meteor.Collection('dogs');
Cats = new Meteor.Collection('cats');
Alpacas = new Meteor.Collection('alpacas');
MyCollections = {
dogs: Dogs,
cats: Cats,
alpacas: Alpacas,
};
...
MyCollections['dogs'].doSomething();

Items in list is never selected

I have a list and setting the list to the exact item that is in it's dataProvider would not select it programmatically. Here is the code:
if (list.selectedItem != iDocument) {
var length:int = documentsCollection.length;
for (var i:int;i<length;i++) {
jDocument = IDocumentData(documentsCollection.getItemAt(i));
if (jDocument.uid==iDocument.uid) {
list.selectedItem = IDocumentData(documentsCollection.getItemAt(i));
break;
}
}
}
There were two issues.
I had applied a sort to the ArrayCollection and the field was not in the item. I had copied code from another project and the field was "#name" since it was an XMLListCollection. The sort field should have been set to "name".
So when you set the selectedItem property it looks in the collection and if the collection has a sort then it looks in the findItem() call which does a compare function that checks if the item has the field name in the item. If not it throws an error. Since I had the incorrect field name an error was thrown. If an error is thrown then the pursuit to find the selected item is abandoned and selected index is -1.
Code from ListCollectionView.as:
try
{
return sort.findItem(localIndex, values, mode, insertIndex);
}
catch (e:SortError)
{
// usually because the find critieria is not compatible with the sort.
}
return -1;
Code from Sort.as:
var hasFieldName:Boolean;
try
{
hasFieldName = values[fieldName] !== undefined;
}
catch(e:Error)
{
hasFieldName = false;
}
if (hasFieldName)
{
if (!hadPreviousFieldName)
{
message = resourceManager.getString(
"collections", "findCondition", [ fieldName ]);
throw new SortError(message);
}
else
{
fieldsForCompare.push(fieldName);
}
}
The second issue was that the List uses an exact equality operator so it uses "===" instead of "==". This means that you have to make sure you are passing in the exact instance of the item in the list.

Linq to XML single or default

I am querying an xml and i am storing the results using singleordefault
var query = from nm in xelement.Descendants("EmployeeFinance")
where (int)nm.Element("EmpPersonal_Id") == empID
select new AllowancePaid
{
gradeTaxId = nm.Element("Allow-GradeTax").Elements("Amount").Attributes("BenListId").Select(a => (int)a).ToList(),
gradeTaxAmt = nm.Element("Allow-GradeTax").Elements("Amount").Select(a => (double)a).ToList()
};
Debug.WriteLine("2");
var resultquery = query.SingleOrDefault();
now this line: var resultquery = query.SingleOrDefault(); works fine if it found in the xml file. However, i have a case where my query will result in a null. If i have no value, it would make an entry in the xml file and my query obviously results in null. My question is how do i cater for this without causing my programe to crash. obviously, singleordefault() doesnt work.
***************** EDITED *************************
I read what everyone said so far and it make sense but i am still having a problem.
if (query.Count() == 0)
{
Debug.WriteLine("NULL");
}
else {
var resultquery = query.SingleOrDefault();
Debug.WriteLine("NOT NULL");
}
OR
if (query == null)
{
Debug.WriteLine("NULL");
}
else {
var resultquery = query.SingleOrDefault();
Debug.WriteLine("NOT NULL");
}
OR
var resultquery = query.SingleOrDefault();
if (resultquery == null)
{
Debug.WriteLine("NULL Result");
}
else
{
Debug.WriteLine("NOT NULL");
}
I am getting a System.NullReferenceException error when the first part of the if statement is true. One user said to do this: var resultquery = query.SingleOrDefault(); then use my if..else statement to do the comparison. However i am getting the error at the point of assign query.singleofdefault() to resultquery. So i am lost.. hope someone can help. thank you
what i am trying to understand is this. the documentation states if the result query is 0 it will give a default value, if it is not, it will be a single value. so why doesnt this give a default value? [taken from the comments]
null is the default value for reference types. Apparently AllowancePaid is a reference type (a custom class).
What is the value you want when the there is no value found.
You could either do:
if (resultquery == null) {
// Logic for No result
} else {
// Logic for result found
}
Or you could force a default value
eg.
var resultquery = query.SingleOrDefault() ?? new AllowancePaid();
UPDATE
From the comments posted it appears that the null reference exception is actually caused within the query itself rather than by the assignment to resultquery and use of later.
This updated query should solve the issue
var query = from nm in xelement.Descendants("EmployeeFinance")
where nm.Element("EmpPersonal_Id") != null
&& (int)nm.Element("EmpPersonal_Id") == empID
&& nm.Element("Allow-GradeTax") != null
&& nm.Element("Allow-GradeTax").Elements("Amount") != null
select new AllowancePaid
{
gradeTaxId = nm.Element("Allow-GradeTax").Elements("Amount").Attributes("BenListId").Select(a => (int)a).ToList(),
gradeTaxAmt = nm.Element("Allow-GradeTax").Elements("Amount").Select(a => (double)a).ToList()
};
var resultquery = query.SingleOrDefault();
if (resultquery == null) {
Debug.WriteLine("NULL Result");
} else {
// Logic here
}

how to update the values while iterating dictionary items?

I have a dictionary:
Dictionary<string, long> Reps = new Dictionary<string, long>();
and I want to update the values while iterating through all items, like this:
foreach (string key in Reps.keys)
{
Reps[key] = 0;
}
it is giving me an error saying:
"Collection was modified; enumeration operation may not execute"
can anyone tell me why it is giving me this error, because I have one more function that adds the value, and it is called when button is clicked:
public static void Increment(string RepId, int amount)
{
long _value = Convert.ToInt64(Reps[RepId]);
_value = _value + amount;
Reps[RepId] = _value;
}
and this function is working fine. so whats the problem when updating all the values? And whats the solution for this?
more simplified, do this:
foreach (string key in Reps.keys.ToList())
{
Reps[key] = 0;
}
and the reason for the error is you are trying to edit the actual object which is in use and if you make a copy of it and then use it like this:
var repscopy = Reps;
foreach (string key in repscopy.keys)
{
Reps[key] = 0;
}
it'll give the same error as it also pointing to the original object, and when the ToList() is added it created a new object of List
The problem is no updating the values, you just cannot change the collection that your foreach() is based on while the foreach is being iterated.
Try somehting like this
List<string> keylist = Reps.keys.ToList();
foreach(string r in keylist)
{
Reps[r] = 0;
}
this would work.
This happens because you are changing the element in the Dictionary<string, long> while looping over it with foreach. Try this.
foreach (string key in Reps.Keys.ToList())
{
Reps[key] = 0;
}
Now you are looping over a list created from the dictionarys key. As it is not the original collection thats modified, the error will go away.

Resources