Flutter - how to store a list in GetStorage? - list

For each article the user browses, I want to save the ID information.
I am using getstorage my code sample is below.
I can not find a true way also, i am looking best way to save id's list.
final box = GetStorage();
List<String> myFavoriteList = [];
saveFav(String id) {
myFavoriteList.add(id);
box.write('favoriteArticles', myFavoriteList.cast<String>());
}
ifExistInFav(String id) async {
bool ifExists = false;
List<String> my = (box.read('favoriteArticles').cast<String>() ?? []);
ifExists = my.contains(id) ? true : false;
return ifExists;
}

First, you need to define your list and convert it to String.
** note that if you use a custom data type ensure you convert your model to String.
then you can use the following to store a List as a String object
final box = GetStorage('AppNameStorage');
/// write a storage key's value
saveListWithGetStorage(String storageKey, List<dynamic> storageValue) async => await box.write(/*key:*/ storageKey, /*value:*/ jsonEncode(storageValue));
/// read from storage
readWithGetStorage(String storageKey) => box.read(storageKey);
the saving procee implemention:
saveList(List<dynamic> listNeedToSave) {
/// getting all saved data
String oldSavedData = GetStorageServices().readWithGetStorage('saveList');
/// in case there is saved data
if(oldSavedData != null){
/// create a holder list for the old data
List<dynamic> oldSavedList = jsonDecode(oldSavedData);
/// append the new list to saved one
oldSavedList.addAll(listNeedToSave);
/// save the new collection
return GetStorageServices().saveListWithGetStorage('saveList', oldSavedList);
} else{
/// in case of there is no saved data -- add the new list to storage
return GetStorageServices().saveListWithGetStorage('saveList', listNeedToSave);
}
}
/// read from the storage
readList() => GetStorageServices().readWithGetStorage('saveList');
then the usage:
onTap: () async => debugPrint('\n\n\n read list items ${jsonDecode(await readList())}\n\n\n', wrapWidth: 800),

Related

How to count a specific length of a list in flutter

I created a task list. I want to count the tasks length like this:
ongoing tasks = task list length - isDone tasks
I want to find the isDone tasks count in this case. As to the picture isDone tasks = 2.
These are the classes that I created.
class Task {
final String taskName;
bool isDone;
Task({required this.taskName, this.isDone = false});
void toggleDone() {
isDone = !isDone;
}
}
........
class Taskdata with ChangeNotifier {
final List<Task> _tasks = [];
UnmodifiableListView<Task> get tasks {
return UnmodifiableListView(_tasks);
}
int get tasksCount {
return _tasks.length;
}
}
You can use the where function to filter a list per a certain condition:
int get tasksCount {
List<Task> tasksLeft = _tasks.where((task) => !task.isDone).toList(); //where returns an iterable so we convert it back to a list
return tasksLeft.length;
}
if something goes wrong, you may need to convert List to Iterable
int get doneCount {
Iterable<Task> tasksDone = _tasks
.where((task) => task.isDone)
.toList(); //where returns an iterable so we convert it back to a list
return tasksDone.length;
}

Flutter Futurebuilder gets modified

I have a Futurebuilder that fetches data from an Api.
I am assigning its data to a list;
List<TicketModel> ticketList = [];`
ticketList = snapshot.data;
Now the weird thing is, snapshot.data and ticketList should be independent right?
However if I remove data from the List e.g I remove every Object that has the price 1 the snapshot.data modifies too(Has same data as list now).
Why is that so?
The Futurebuilder is in a Modal bottom sheet if that's necessary
void main() {
List<String> listofAllTickets =[];
listofAllTickets = ["ticket eins","ticket zwei", "ticket drei"];
List<String> listOfAllTicketsSecond = listofAllTickets;
listOfAllTicketsSecond.removeWhere((element) => element == "ticket eins");
print(listofAllTickets);
print(listOfAllTicketsSecond);
}
you need to use a futurebuilder and connect ticketlist to it. the futurebuilder will generate a snapshot in its callback function. you can not access the snapshot outside of the futurebuilder.
I prefer using Bloc and streambuilder. Streambuilder events occur when change occurs on the notification stream.
As #Jeppe posted in the comments what I did before was that:
void main() {
List<String> listofAllTickets =[];
listofAllTickets = ["ticket eins","ticket zwei", "ticket drei"];
List<String> listOfAllTicketsSecond = listofAllTickets;
listOfAllTicketsSecond.removeWhere((element) => element == "ticket eins");
print(listofAllTickets);
print(listOfAllTicketsSecond);
}
the right solution would be doing this:
void main() {
List listofAllTickets = ["ticket eins","ticket zwei", "ticket drei"];
List listOfAllTicketsSecond = [];
listOfAllTicketsSecond = List.from(listofAllTickets);
listOfAllTicketsSecond.removeWhere((element) => element == "ticket eins");
print(listofAllTickets);
print(listOfAllTicketsSecond);
}
In Example two I am copying the data instead of referencing the list.

Apollo: How to Sort Subscription Results in UpdateQuery?

Here is a working Apollo subscription handler:
componentDidMount() {
const fromID = Meteor.userId();
const {toID} = this.props;
this.toID = toID;
this.props.data.subscribeToMore({
document: IM_SUBSCRIPTION_QUERY,
variables: {
fromID: fromID,
toID: toID,
},
updateQuery: (prev, {subscriptionData}) => {
if (!subscriptionData.data) {
return prev;
}
const newIM = subscriptionData.data.IMAdded;
// don't double add the message
if (isDuplicateIM(newIM, prev.instant_message)) {
return previousResult;
}
return update(prev, {
instant_message: {
$push: [newIM],
},
});
}
});
}
instant_message is an array of objects to be displayed. Each object contains a date field. I need to sort the objects in this array by date.
This approach used to work with beta versions of Apollo:
//update returns a new "immutable" list
const instant_message = update(previousResult, {instant_message: {$push: [newAppt]}});
instant_message.instant_message = instant_message.instant_message.sort(sortIMsByDateHelper);
return instant_message;
I can sort the array, but Apollo throws an error with the returned object-- e.g. it is not found in props when the render routine needs it.
What is the correct way to return the sorted array from updateQuery? Thanks in advance to all for any info.
It turns out it wasn't the sorting that was causing the anomaly. It appears that subscriptions fail if the __TYPENAME of the returned object doesn't match something else here -- either the varname used in this routine ('instant_message' in the above code), or the varname of the array of objects returned in props to the render function. Lining up all these things so that they are identical fixes it.

Doctrine 2 nested set - retrieve full tree in single query

I'm using stof/StofDoctrineExtensionsBundle (Bundle wrapper for Atlantic18/DoctrineExtensions) to implement a Nested Set (tree) entity. The entity is configured and working, but I can't figure out how to retrieve all root notes with all of their children (full trees) in a single query. I currently have the full collection returning however it lazy loads all children, meaning a large number of queries is performed.
Thanks for any help.
You can just use childrenHierarchy() method for whole tree retrieve:
$tree = $repo->childrenHierarchy();
Found a solution.
retrieve full list of node objects:
$repo = $this->getDoctrine()->getManager()->getRepository('NestedEntity');
$nodes = $repo->getChildren();
build tree with your nodes.
$tree = $repo->getRepoUtils()->buildTreeArray($nodes);
buildTreeArray method accepts array of node-arrays, so you must implement ArrayAccess interface in your Entity. Also it puts all children in __children key of node-array.
/**
* #Gedmo\Tree(type="nested")
* #ORM\Table(name="nested_entity")
* #ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
*/
class NestedEntity implements \ArrayAccess
{
public function offsetExists($offset)
{
return property_exists($this, $offset);
}
public function &offsetGet($offset)
{
return $this->$offset;
}
public function offsetSet($offset, $value)
{
$this->$offset = $value;
}
public function offsetUnset($offset)
{
$this->$offset = null;
}
protected $__children = [];
...

Reflection on EmberJS objects? How to find a list of property keys without knowing the keys in advance

Is there a way to retrieve the set-at-creations properties of an EmberJS object if you don't know all your keys in advance?
Via the inspector I see all the object properties which appear to be stored in the meta-object's values hash, but I can't seem to find any methods to get it back. For example object.getProperties() needs a key list, but I'm trying to create a generic object container that doesn't know what it will contain in advance, but is able to return information about itself.
I haven't used this in production code, so your mileage may vary, but reviewing the Ember source suggests two functions that might be useful to you, or at least worth reviewing the implementation:
Ember.keys: "Returns all of the keys defined on an object or hash. This is useful when inspecting objects for debugging. On browsers that support it, this uses the native Object.keys implementation." Object.keys documentation on MDN
Ember.inspect: "Convenience method to inspect an object. This method will attempt to convert the object into a useful string description." Source on Github
I believe the simple answer is: you don't find a list of props. At least I haven't been able to.
However I noticed that ember props appear to be prefixed __ember, which made me solve it like this:
for (f in App.model) {
if (App.model.hasOwnProperty(f) && f.indexOf('__ember') < 0) {
console.log(f);
}
};
And it seems to work. But I don't know whether it's 100% certain to not get any bad props.
EDIT: Adam's gist is provided from comments. https://gist.github.com/1817543
var getOwnProperties = function(model){
var props = {};
for(var prop in model){
if( model.hasOwnProperty(prop)
&& prop.indexOf('__ember') < 0
&& prop.indexOf('_super') < 0
&& Ember.typeOf(model.get(prop)) !== 'function'
){
props[prop] = model[prop];
}
}
return props;
}
Neither of these answers are reliable, unfortunately, because any keys paired with a null or undefined value will not be visible.
e.g.
MyClass = Ember.Object.extend({
name: null,
age: null,
weight: null,
height: null
});
test = MyClass.create({name: 'wmarbut'});
console.log( Ember.keys(test) );
Is only going to give you
["_super", "name"]
The solution that I came up with is:
/**
* Method to get keys out of an object into an array
* #param object obj_proto The dumb javascript object to extract keys from
* #return array an array of keys
*/
function key_array(obj_proto) {
keys = [];
for (var key in obj_proto) {
keys.push(key);
}
return keys;
}
/*
* Put the structure of the object that you want into a dumb JavaScript object
* instead of directly into an Ember.Object
*/
MyClassPrototype = {
name: null,
age: null,
weight: null,
height: null
}
/*
* Extend the Ember.Object using your dumb javascript object
*/
MyClass = Ember.Object.extend(MyClassPrototype);
/*
* Set a hidden field for the keys the object possesses
*/
MyClass.reopen({__keys: key_array(MyClassPrototype)});
Using this method, you can now access the __keys field and know which keys to iterate over. This does not, however, solve the problem of objects where the structure isn't known before hand.
I use this:
Ember.keys(Ember.meta(App.YOUR_MODEL.proto()).descs)
None of those answers worked with me. I already had a solution for Ember Data, I was just after one for Ember.Object. I found the following to work just fine. (Remove Ember.getProperties if you only want the keys, not a hash with key/value.
getPojoProperties = function (pojo) {
return Ember.getProperties(pojo, Object.keys(pojo));
},
getProxiedProperties = function (proxyObject) {
// Three levels, first the content, then the prototype, then the properties of the instance itself
var contentProperties = getPojoProperties(proxyObject.get('content')),
prototypeProperties = Ember.getProperties(proxyObject, Object.keys(proxyObject.constructor.prototype)),
objectProperties = getPojoProperties(proxyObject);
return Ember.merge(Ember.merge(contentProperties, prototypeProperties), objectProperties);
},
getEmberObjectProperties = function (emberObject) {
var prototypeProperties = Ember.getProperties(emberObject, Object.keys(emberObject.constructor.prototype)),
objectProperties = getPojoProperties(emberObject);
return Ember.merge(prototypeProperties, objectProperties);
},
getEmberDataProperties = function (emberDataObject) {
var attributes = Ember.get(emberDataObject.constructor, 'attributes'),
keys = Ember.get(attributes, 'keys.list');
return Ember.getProperties(emberDataObject, keys);
},
getProperties = function (object) {
if (object instanceof DS.Model) {
return getEmberDataProperties(object);
} else if (object instanceof Ember.ObjectProxy) {
return getProxiedProperties(object);
} else if (object instanceof Ember.Object) {
return getEmberObjectProperties(object);
} else {
return getPojoProperties(object);
}
};
In my case Ember.keys(someObject) worked, without doing someObject.toJSON().
I'm trying to do something similar, i.e. render a generic table of rows of model data to show columns for each attribute of a given model type, but let the model describe its own fields.
If you're using Ember Data, then this may help:
http://emberjs.com/api/data/classes/DS.Model.html#method_eachAttribute
You can iterate the attributes of the model type and get meta data associated with each attribute.
This worked for me (from an ArrayController):
fields: function() {
var doc = this.get('arrangedContent');
var fields = [];
var content = doc.content;
content.forEach(function(attr, value) {
var data = Ember.keys(attr._data);
data.forEach(function(v) {
if( typeof v === 'string' && $.inArray(v, fields) == -1) {
fields.push(v);
}
});
});
return fields;
}.property('arrangedContent')