I just started to use observable list in dart. It notifies when the list is updated. When it's a removing case, it only gives me the index it removes from and how many items were removed. How am I supposed to know which items were removed since I only have indices and the 'updated' list (the items have already been removed from it.) I want to know if I miss something before I manually put extra code in it.
Thanks,
yi
The List removeAt() method returns the removed object. So, you can simply assign the value of removeAt() to a variable, like this:
var list = [obj0, obj1, obj2];
var first = list.removeAt(0);
Related
I have a list of constructed objects called RecentCard which is basically an object with user id, pic, and name. I have created a list arranged in order of most recent interaction based on timestamp. However i need to get rid of the second occurence and onwards of any duplicated object. I am comparing just the ids since users may have the same name or photo, and i cannot remove duplicates from a simple list of uids because then i could lose the order of corresponding photos and names.
For example the list would look something like this :
List<RecentCard> recentCards= [RecentCard(uid:as721dn18j2,name:mike,photourl:https://sadadasd1d1),RecentCard(.....]
I have searched for solutions but all of them are dealing with like primitive types like simple lists of strings and the solutions didn't work for me. For example this post: How to delete duplicates in a dart List? list.distinct()? Read below
The first answer's link is no longer available, the next answer with sets is something i tried but it simply doesnt work i have no idea why maybe because its not a primitive type. The next answer with the queries package didn't work because i was using the list to build a listview.builder and so when i called list.length it said i couldnt call that on an iterable or something. The final solution wouldn't work because it said String is not a subtype of RecentCard.
I tried using two forloops with the second just comparing first value to the next couple but that doesnt work because if a duplicate is found, the object is removed and the length is messed up so some elements get skipped.
Any ideas? I feel like its very simple but im not sure how to do it.
You have to use Set to store seen cards and then filter away those ones that are already in the set.
final seenCards = Set<String>();
final uniqueCards = recentCards.where((card) => seenCards.add(card.uid)).toList();
following scenario:
I have a Firebase database containing a list that is used to create a set of "paper-cards" with dom-repeat:
<template is="dom-repeat" items="{{items}}">
<my-element card="{{item}}">
<paper-card id="{{card.id}}">
...
</paper-card>
</my-element>
</template>
In the UI, the user can add or delete paper-cards, so items also get deleted in Firebase.
Now I realized if I change the CSS of an element (e.g. fadeIn, fadeOut animation) and afterwards delete a card and later add one card, the card still has the CSS state as it was before (e.g. for fadeIn/fadeOut animations).
My questions:
How does DOM repeat deal with elements added or removed? Is not all information of this element "deleted"?
If I delete item #5 (out of 10), what happens to elements 6-10, are they deleted and re-created as "5-9" or "moved/altered"?
Besides CSS, are there any other implications that should be considered inside the template tag? Do I need to manually reset anything?
You can read about the dom-repeat on https://www.polymer-project.org/1.0/docs/api/dom-repeat but what it basically tells you that it tries to be too smart without asking the developer if it wants that behavior. The dom-repeat is heavily flawed because of this.
Polymer is saving performance to doing a dirty check, basically looping through everything and only changing the DOM if the checked values (id, in this case) changes. This means that it will inherit other values.
Basically, it wont update sub-properties. This means that dom-repeat isn't really made for any kind of update.
You can possibly go around this issue by using Polymer's this.splice(). It works like the splice in javascript but sends out an event to dom-repeat to update and where to update. Remember however, that arrays in Javascript are references, so if you take this.items and try to modify it, it will automatically update values the dom-repeat (without updating DOM) and then it will dirty check the update with the new values and not change anything at all. If you want to modify the array in the dom-repeat, then use JSON.parse(JSON.stringify(array) first to get rid of the reference.
Another thing you can do is to use the unique id. If the id changes for that specific card, then hard reset all values and initialize that specific card once again with all it's normal properties (including CSS). That's the workaround I use all the time.
The desperate thing to do, when nothing else works, is to nullify the array that keeps track of the cardset, with this.set('items', []) and then set the property with the new array.
The repeater evaluates the number of items in your array on initialization and stamps that many template instances into the DOM. If you delete an item from your array the repeater is presented with a new array that is one element less, removes the last one and propagates data change to elements' instances.
So if you start with 10 elements and order to delete #5 then element's #6 data is inserted via data-binding into the same DOM node that previously contained #5 data, and so on down the list. The last DOM node for which the updated array contains no data will be removed from the DOM tree.
Say for instance, I have a list of objects (obj1). Within each record of the obj1, there's a field value (var1). Is there anyway to add all the values of var1 within the list of obj1 to another list without looping through the list of obj1?
Please let me know if I am being unclear on what I am asking for above.
Thanks in advance for any help/clarifications.
I think what you are looking for are SOQL Aggregate Functions, which will let you do something like this:
SELECT SUM(Amount)
FROM Opportunity
WHERE IsClosed = false AND Probability > 60
That way you don't have to loop in your code and push the SUM operation to the database. On a related note, you might also want to look at Roll-Up Summary Fields in case you want to maintain this summation on a parent object.
I have a query about class init functions in Python. I was messing about trying to create a text adventure game type environment, with each room having an "items" property, stored as a list. I tried the following:
class Room:
def __init__(self,items=[]):
self.items=items
But what I find with this is that every room that does not have an item defined on initiation gets not only an empty list, but the same empty list. Now if I create a bunch of rooms and append an item to one of them, the item appears in every room.
Easy enough to fix (manually assign an empty list to every room) but I don't understand why this happens. I would imagine creating room a would create a.items as an empty list, and room b would create b.items. But can anyone explain why these would be identical? And is there a way to produce the above function with a default value that creates a different list each time?
Cheers,
Billy.
You have to understand default parameters in python.
When you write items=[], you create a global variable [], that you assign to item when a proper parameter is not provided.
This means every time items take the default value, it will be assigned the same [] object.
(Remember, as in Java, variables are just references to objects. All items variables will be references to the same object).
Formal explanation :
http://effbot.org/zone/default-values.htm
What you could do is :
def __init__(self, items=None):
if items is None:
items = []
self.items = items
this way, the default value, None, is never changed. When that is spotted, a new list is created (a real new list this time, not a global one).
I have a spark list, which is based on a dataProvider. As the application runs, the data in the dataprovider can change, and also the dataProvider can be swapped for a different one
What I need to do is make sure that something is always selected in the list (unless it is empty)
You simply have to set the property requireSelection of your list instance to true.
In MXML, it would be:
<s:List id="myList" requireSelection="true">
After setting its data provider ( or whenever is changed ) you could do a:
myList.selectedIndex = 0;
, so whenever the is data on your list, its first item will be selected (it could be any index, just remember that it start from 0 to length - 1).