Access has Many via foreach in computed property in ember - ember.js

So I've got a hasMany defined as so
quests: DS.hasMany('quest')
I have a property that is supposed to go through each quest and work out the total.
The function looks like this,
questXP: function() {
var amount = 0;
this.get('quests').forEach(function(item)
{
console.log(item.get('xpReward'));
amount += parseInt(item.get('xpReward'));
});
return amount;
}.property('quests'),
I've tried adding async: true to the hasMany but it stops the forEach from working at all. At the moment it loops 3 times(I have 3 quests) but it isn't able to access any of the quest's properties.
My thought is it's related to the fact that the quests are still being loaded.
Any ideas on what I'm doing wrong?

Your computed property depends of each xpReward property. So you need to use quests.#each.xpReward istead of quests.
questXP: function() {
var amount = 0;
this.get('quests').forEach(function(item)
{
console.log(item.get('xpReward'));
amount += parseInt(item.get('xpReward'));
});
return amount;
}.property('quests.#each.xpReward'),

Related

Flutter - how to store lists of Strings: (GetStorage or Shared Preferences). using android

So, I have come across a solution for this problem using Get_storage thanks to a couple of great explanations about the topic. I managed to work with getx and the Provider package to save data when adding new stuff and reading it when starting the application (thats the behavior i'm going for here). Said that, i'm having a hard time trying to remove data from memory.
Context
The project is a to-do list app, the front end is working perfectly, but when it comes to storage it gets more complicated. The thing is that i'm very new to flutter and mobile development, i recieved some help but this kind of stuff is still foggy in my brain, i could not remove data using the same logic. When i called box.Remove('key') like the docs say, my ENTIRE list got removed. I don't have a single clue why that happaned.
And so i wonder if i could understand it more by reading through some more explanations, i know Shared Preferences is a great deal do work with this kind of situation, but i would also be confortable with a solution using get_storage since i'm more familiar with it.
the code:\
I'm calling these lists inside a listView on a different file with the help of Provider - -
List<Task> _tasks = [
Task(
name: "Title",
description: "Description",
),
];
Adding tasks to my ListView - -
void add(String newTitle, newDesc) {
final task = Task(name: newTitle, description: newDesc);
_tasks.add(task);
notifyListeners();
}
Here is the removal of a task from the ListView - -
void removeTasks(Task task) {
_tasks.remove(task);
notifyListeners();
}
I tried to implement a logic to write and read data, it worked. But i also tried to use this removeTasks method to remove from storage as well by calling box.Remove('tasks'); ('tasks' was the key passed to the writing and reading methods). It removed everything from memory since my listview got empty.
Since i'm not that experienced, i went through the documentation and could understand some of the SharedPreferences Explanation (same with got_storage) but i'm having a hard time when trying to apply it to my code.
I would appreciate any help using get_storage OR shared preferences to this problem.
Where i'm calling the deletion:
// bool variables that control the state of the screen
// since i can change it to show done tasks or on goind tasks
// dont mind that, i think its irrelevant to the problem.
//
bool isActiveDoing = true;
bool isActiveDone = false;
List finalArray = []; //it will store the tasks
class TaskList extends StatefulWidget {
#override
_TaskListState createState() => _TaskListState();
}
class _TaskListState extends State<TaskList> {
#override
Widget build(BuildContext context) {
//dont mind the if else as well, its not part of the problem
//just using it to handle the state of the screen
if (isActiveDoing) {
finalArray = Provider.of<TasksFunctions>(context).tasks;
}
//TasksFunctions is a class with methods on regards to the storage
//it contains add tasks, remove, etc... i'm using provider to
//link those to the screens with the notifyListeners
if (isActiveDone) {
finalArray = Provider.of<TasksFunctions>(context).doneTasks;
}
//now here is where i call the class tha has the deletion method
return Consumer<TasksFunctions>(
builder: (context, tasksFunctions, child) {
return ListView.builder(
//list view tha has all the tasks
itemCount: finalArray.length,
itemBuilder: (context, index) {
final task = finalArray[index];
//using the slidableWidget to wrap the deletion method
return SlidableWidget(
onDismissed: (action) {
if (isActiveDoing) {
Provider.of<TasksFunctions>(context, listen: false)
.removeTask(task);
//so here is where i'm deleting those tasks, calling that method
//listed up on this post
}
if (isActiveDone {
Provider.of<TasksFunctions>(context, listen: false)
.removeDone(task);
}
},
);
},
);
},
);
}
}
So i spent some time translating the code, but i think that it does not match any of flutter's good practices principles.
I also tried calling storageList.remove(task); and then rewriting it with the box.write('tasks', storageList); but nothing was removed from the memory (maybe because i didn't loop through the whole storageLists searching for the right index i guess)
Sounds like your code is based on my answer to your original question about this.
If that's the case, then the key tasks is the key to the entire list of maps, not a single map or Task. So it's behaving as expected when it wipes all of your tasks.
In order to persist any changes, you'd have to remove that particular map (Task) from storageList then overwrite the box again with box.write('tasks', storageList); It will save over the same list of maps and persist any deletions you made.
If you share your code where you're trying to delete the task and whats going on around it I can give you a more specific example.
EDIT: Answering question in comments.
If you wanted to go the UniqueKey route you wouldn't need the index at all. You could do something like this.
class Task {
final String name;
final String description;
final String key; // not an actual Key but will take the String value of a UniqueKey
Task({this.key, this.name, this.description});
}
When you add a new Task it would look like this.
final task = Task(
description: 'test description',
name: 'test name',
key: UniqueKey().toString());
Then you could use a Map of maps instead of a list of maps and use the key for both.
Map storageList = {};
void addAndStoreTask(Task task) {
_tasks.add(task);
final Map storageMap = {}; // temporary map that gets added to storage
storageMap['name'] = task.name;
storageMap['description'] = task.description;
storageMap['key'] = task.key;
storageList[task.key] = storageMap; // adding temp map to storageList
box.write('tasks', storageList); // adding map of maps to storage
}
Then your restore function would look like this:
void restoreTasks() {
storageList = box.read('tasks'); // initializing list from storage
storageList.forEach((key, value) { // value here is each individual map that was stored
final task =
Task(name: value['name'], description: value['description'], key: key);
_tasks.add(task);
});
}
Then when you go to delete, you iterate through the list and find the matching key.

QML Map: Large amount of displayed items

I have a performance issue while displaying large amounts MapItems on a Map provided by the QML Location module. I already asked the question here (https://forum.qt.io/topic/79229/large-amount-of-qml-mapitems), but nobody could help me, so I wanted to try it here once. I also found this question (How to use the QML/QtLocation module for displaying a large amount of offline data on a map?), but before adding another dependency, I wanted to see if my code can be improved so that QML can handle this situation without any help.
I am currently trying to plot a large amount of items onto a QML Map (30,000 - 120,000 points). These items shall be updated dependent of the position of a QSlider. Performance decreases strongly from about 1,000 items upwards, when I use 30,000 it takes several minutes until the QML Map has all the data visualized and is responsive again. I have a machine which is absolutely capable of fulfilling this task in general, so I think the problem is QML. I am using Qt 5.8.
Is there any way to improve this performance or is it just not possible with a QML-map to plot so many MapItems at a time? I tried MapCircles, Polylines, Polygons and MapQuickItems with images, but for me it seems like the performance issue just arises from adding this amount of MapItems, as I could not see a significant difference in processing time between these types.
I have more data on the map visualized, which should not be refreshed every time the QSlider is moved. Even though I tried just to clear all MapItems and add the new ones for performance tests, but even this did not improve the performance.
My code (a bit abstracted) looks like this:
///-------------- Widget.cpp-----------------///
void ProcessInput(int qslider_pos) {
QVariantList lat_vec;
QVariantList lon_vec;
// Fill vectors with lateral and longitudinal positions
// ...
// Clean current points on map and draw new ones
SendToQmlFuncRemovePoints();
SendToQmlFuncAddPoints(lat_vec, lon_vec);
}
void QmlConnector::SendToQmlFuncRemovePoints()
{
QVariant returnedValue;
QMetaObject::invokeMethod(QmlMapSingleton::instance()->GetRoot(), "remove_points",
Q_RETURN_ARG(QVariant, returnedValue));
}
void QmlConnector::SendToQmlFuncAddPoints(QVariantList input_one, QVariantList input_two)
{
QVariant returnedValue;
QMetaObject::invokeMethod(QmlMapSingleton::instance()->GetRoot(), "add_points",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, QVariant::fromValue(input_one)), Q_ARG(QVariant, QVariant::fromValue(input_two)));
}
.
///-------------- Map.qml -----------------///
Map {
anchors.fill: parent
property variant points: ({})
property int pointCounter: 0
Plugin
{
id: osmplugin
name: "osm"
PluginParameter { name: "osm.mapping.highdpi_tiles"; value: true }
}
Component.onCompleted: {
points = new Array();
}
id: map
plugin: osmplugin
//Javascript functions
function add_points(array_lat, array_lon) {
var myArray = new Array()
var component = Qt.createComponent("mapcircle.qml");
for (var i=0; i<array_lat.length; i++)
{
var object = component.createObject(map, { "center": QtPositioning.coordinate(array_lat[i], array_lon[i]})
map.addMapItem(object)
myArray.push(object)
}
map.points = myArray
}
function remove_points() {
var count = map.points.length
for (var i = 0; i<count; i++){
map.removeMapItem(map.points[i])
map.points[i].destroy()
}
map.points = []
}
}
.
///-------------- mapcircle.qml -----------------///
import QtQuick 2.0
import QtLocation 5.6
MapCircle {
radius: 1
border.width: 0
color: 'green'
}
Qt says that the performance decreases with the number of elements added to the map. Do you need all the points to be visible on the map in the same time, if not you can play around with visibility.
Can't you use QQuickPaintedItem to paint the points in C++ and wrap it into an MapQuickItem, if you have multiple polygonsfor e.g? But also there are some limitation, you cannot have to big images displayed.
If you need all the points maybe you can have different points based on the map zoom level and reduce the number of points added to the map at small zoom level, as was recommended on the other group ...

Sitecore, moving item takes multiple tries

I have a saving event handler in Sitecore where when the date of an item changes (from say 8/7/2014 to 9/7/2014) I want it to be moved into another folder.
It currently somewhat does that, but only if I change the date twice.
If I go from 8/7/2014 > 9/6/2014 it does nothing. If I then change the same item's date to 9/7/2014 it moves it into the correct folder.
If I debug the code it follows the exact same path both times .. anyone have a reason as to why this might be happening?
One of the other problems was that the saving handler was running twice, once with the new date value, once with the old. Changing to the saved handler worked much better because I only have access to the newly saved values, not the old and new values.
Since there were a few comments asking for it, here's the working code to move and item from folder parent to parent > year > month. Keep in mind this is using glassmapper so it would be slightly different if not using glass mapper.
protected void MoveItemToMonthDateFolder<T>(T scItem, Func<T, DateTime> dateSelector, Models.Item parentFolder) where T : Models.Item
{
var date = dateSelector(scItem);
if (!parentFolder.Children.Any(x => x.Name.Contains(date.Year.ToString())))
{
var yearFolder = sitecoreService.Create(parentFolder, new Folder { Name = date.Year.ToString() });
var monthFolder = sitecoreService.Create(yearFolder, new Folder { Name = date.Month.ToString() });
sitecoreService.Move(scItem, monthFolder);
}
else
{
var yearFolder = parentFolder.Children.First(x => x.Name.Equals(date.Year.ToString(), StringComparison.CurrentCultureIgnoreCase));
var monthFolder = yearFolder.Children.FirstOrDefault(x => x.Name.Equals(date.Month.ToString(), StringComparison.CurrentCultureIgnoreCase));
if (monthFolder == null)
{
monthFolder = sitecoreService.Create(yearFolder, new Folder { Name = date.Month.ToString() });
}
sitecoreService.Move(scItem, monthFolder);
}
}

Ember context passed to a view

I'm trying to figure out what's wrong about sending action from parentView to one of its children view:
I've made a PhotoUploadView used to resize and then upload images; it adds canvas drawing the resized image in a div inside its template:
<div class="img-list">
//here the canvas will be added
</div>
The action "saveImages" in this view, acts like this:
var list = this.$('.img-list');
$.each(list.children(), function(index, value) {
//here the code to save
}
But this action is not called directly; because I need to save not only the images but also some records (an offer record and many products records, children of the offer; the images are associated to the product record);
So I have the action "save" on the parentView that is like this:
//save records
offer.save().then(function(savedOffer) {
newProducts.forEach(function(product, indexP) {
product.set('offer', savedOffer);
product.save().then(function(savedProduct) {
}
}
}
//save photos by cycling the PhotoUploadViews that are inside ProductViews that are inside the mainView
this.get('childViews').forEach(function(view, index) {
if (index >= 4) { //the childView from the 4th are the ProductViews
var productId = view.get('product').get('id');
var folder = 'offer-' + controller.get('model').get('id') + '/product-' + productId + '/';
view.get('childViews')[0].send('saveImages', folder, productId); //the first childView of a ProductView is the UploadView
}
});
Well, this works and save the images correctly when you add images to an existing offer with existing product; but when you are creating a new offer, it fails since the folder will becone "offer-undefined/product-undefined" because of course you must wait the records to be saved in order to get their ID;
So I'm trying now to move the send action into the .then callback of product save:
var childViews = this.get('childViews'); //the childView starting from the 4th are the productsViews
offer.save().then(function(savedOffer) {
newProducts.forEach(function(product, indexP) {
product.set('offer', savedOffer);
product.save().then(function(savedProduct) {
var currentPview = (childViews[4 + indexP]); //get the productView associated with the current product
var productId = savedProduct.get('id');
var folder = 'offer-' + savedOffer.get('id') + '/product-' + productId + '/';
currentPview.get('_childViews')[2].send('saveImages', folder, productId); //the object at index 2 of _childViews array is the photoUploadView
Here, the folder is built correctly but after sending action, the saveImages action crashes saying that list is undefined; trying to log the value of "this" inside "saveImages" I can see that also its value is undefined; Someone can please explain why calling the action from one point, it works, and calling it inside the .then callback of product save it doesn't?
I also would like to understand why in the first case I can do
.get('childViews')[0]
to get the PhotoUploadView, but in the second I must do
.get('_childViews')[2]
since using get('childViews) it doesn't work anymore; What is the difference between childViews and _childViews? And why _childViews has more elements than childView?

jQuery Equal Height Columns

http://shoes4school.project-x.me/get-involved.html
Can someone please tell me what i'm doing wrong the the jQuery column faux... I can not get it to work after trying several different methods...
The code i'm using is... my url is above
$j(".content-block").height(Math.max($("#right").height(), $(".content-block").height()));
How to faux columns on webpage
(function($){
// add a new method to JQuery
$.fn.equalHeight = function() {
// find the tallest height in the collection
// that was passed in (.column)
tallest = 0;
this.each(function(){
thisHeight = $(this).height();
if( thisHeight > tallest)
tallest = thisHeight;
});
// set each items height to use the tallest value found
this.each(function(){
$(this).height(tallest);
});
}
})(jQuery);
Firebug show this error :
preloadImages is not defined
preloadImages([