Flutter How to search a spesific map inside of list? - list

I have 3 selectable item on my UI.
I created these with ListViewBuilder. My goal is upload the selectedItem's to Firebase. Anyway, in example;
List<Map<String?, dynamic>> selectedItems = List.empty(growable: true);
List is gonna be like this right before uploading Firebase:
List selectedItems = [
{
'title': selectedItem[index].title,
'price': selectedItem[index].price,
},
];
This has to be my selectedItems list.
And I upload this list as Map like this:
Map<String, dynamic> updatedData = {'items': selectedItems};
This has to be like this in order to Firebase design.
First of all when the user has clicked to item I want to check selectedItems list.
Here is my code but it doesn't work at all:
if (selectedServices.contains(
[{
'title': selectedItem[index].title,
'price': selectedItem[index].price,
}])
The problem is right up here. After this check (also it's always passing because not working) I try to remove same items from selectedItems with this code:
selectedServices.removeWhere((item) => mapEquals(
item,
({
'title': selectedItem[index].title,
'price': selectedItem[index].price,
})));
But it doesn't work too because of the check always passing false. After these steps, my onPressed function working just on this else code bloc.
else
{
selectedServices.addAll([{
selectedItem[index].title:
selectedItem[index].price
}
]);}
A little summary;
.contains method not working like this. If there is another way to set list of maps, just let me learn that. This is important for me but I can't figure it out last few days.
And lastly, can you explain answer how it works for Dart ?

Edit: Focus of the question changed, so this answer now tries to achieve a contains like functionality for lists with complex items.
For a custom equality check a similar functionality to contains can be achieved via any:
import 'package:collection/equality.dart';
void main() {
final map1 = {
'title': 'item1',
'price': 12.34,
};
final map2 = {
'title': 'item2',
'price': 3.45,
};
final list = [map1, map2];
final test1 = list.any((item)=>MapEquality().equals(item, {
'title': 'item1',
'price': 12.34,
}));
print(test1);
final test2 = list.any((item)=>MapEquality().equals(item, {
'title': 'item3',
'price': 14.34,
}));
print(test2);
}
print is:
true
false
you could run into precision issues with doubles, though, or if you are using complex key-value pairs in your maps.

Don't you try to check if array contains other array in this code:
if (selectedServices.contains(
[{
'title': selectedItem[index].title,
'price': selectedItem[index].price,
}])
?
Try to check with one item in parameter-list:
if (selectedServices.contains(
{'title': selectedItem[index].title}
))

Related

Highcharts - On and Off over Time

This hopefully is an easy questions.
I'm using Highcharts through chartit in Django and can get most of my graphs to work (temp and time). I'm now trying to graph the values ON and OFF over time. It seems that highcharts can't interpret the strings in the Y Axis (ON and OFF). Is there a way to get it to use those values?
I've tried using something like this in the chart_option section.
'yAxis': {
'categories': ['ON', 'OFF'],
'title': {'text': 'Status'}}
Many thanks!
Point's y coordinate in series' data must be a number, so you would have to process your data to have it in required format. It would be for the best to do this server side and provide proper data for JS, but if that is not possible then you could process data in JS.
$(function() {
var data = ['ON', 'OFF', 'OFF', 'ON'],
processedData = [];
Highcharts.each(data, function(point) {
processedData.push(point === 'ON' ? 1 : 0);
});
$('#container').highcharts({
'yAxis': {
'categories': ['ON', 'OFF'],
'title': {
'text': 'Status'
}
},
series: [{
data: processedData
}]
});
});
Example: http://jsfiddle.net/ptu6qhjy/

How to create a multi-use partial "template" in AngularJS?

I have a large list of items. Each item has it's own details.
In my main view/partial, I simply display a large list list of the item names.
When the user clicks on an item, I want the page to go to a partial which works as a "template", displaying information based on which list item is clicked, and hence possibly what the URL looks like. E.g. /listItem1/
This diagram below hopefully sums up what I want to achieve pretty clearly.
How can I do this?
Right now, I have a pretty standard set up in which I have all the information for each list item in an array of object literals, which is contained in a controller injected into the main app module. Like so:
var app = angular.module('app', [/*nodependencies*/]);
var controllers = {};
app.controller(controllers);
controllers.listController = function ($scope){
$scope.list = [
{name: 'List Item 1 Name', detail1: 'blahblah1', detail2: 'blahblah2'},
{name: 'List Item 2 Name', detail1: 'blahblah1', detail2: 'blahblah2'},
{name: 'List Item 3 Name', detail1: 'blahblah1', detail2: 'blahblah2'}
..... and so on
I know how to create basic views/partials as well. But what would be my next steps?
You can do what you want, using the built-in router which ships with AngularJS.
var app = angular.module('app', [/*nodependencies*/])
.config(function($routeProvider) {
$routeProvider
.when('/:itemId', {
templateUrl: '/path/to/partial',
controller : function($scope, $routeParams) {
$scope.item = $routeParams.itemId;
}
})
});
Basically, what the above means, is that if you browse to pdf/item/1
Then you will have access in your controller to $routeParams.itemId which will be equal to 1. You can then do whatever logic is necessary with this information on your partial to show the information you want.
Hope this helps.
Update
Please look at the controller, this is how you would get the param you passed via the URL, you would then do whatever it is you need to do with that param in the controller, and pass the data back to the view.
You can create a small directive that will use the multi-use partial to display each item on the list
Take a look at this working example (http://plnkr.co/edit/0jNVxRg6g3p8uxpustzz?p=preview)
var myApp = angular.module('myApp', []);
myApp.controller('listController', ['$scope', function ($scope) {
$scope.list = [
{
name: 'List Item 1 Name',
url: 'pdfs/item1.pdf',
detail: 'blahblah'
},
{
name: 'List Item 2 Name',
url: 'pdfs/item2.pdf',
detail: 'blahblah'
},
{
name: 'List Item 3 Name',
url: 'pdfs/item3.pdf',
detail: 'blahblah'
}
];
$scope.selectItem = function(item){
$scope.selected = item;
}
}]);
myApp.directive('listItem', [function () {
return {
restrict: 'A',
scope: {
item: '='
},
templateUrl: 'multiple-partial.html',
link: function (scope, element, iAttrs) {
}
};
}])

How to hit non REST endpoints with Ember Data 1.0 beta

My API is mostly restful except I have a /search endpoint on some resources. I'm using the DS.ActiveModelAdapter and DS.ActiveModelSerializer and everything is great.
My current implementation for search is somewhat like this:
makeAPICall: ->
#set('loading', true)
states = #get('selectedStates')
statesString = states.join(',')
query = #get('searchParam')
url = "/api/v1/organizations/search?#{statesString}&query=#{query}"
$.get(url).then (data) =>
#get('store').pushPayload(data)
# TODO this needs to go through the adapter.
orgs = data.organizations.map (org) =>
#store.find('organization', org.id)
#set('organizations', orgs)
#set('loading', false)
The problem is that I don't know how to do all the normalization/camelization that happens in the adapter in this case. Because the template relies on the #get('organizations') in this case, some underscored attributes don't show up.
What is the correct way to implement this?
The pushPayload is suposed to do the normalization/camelization but needs to know the type you are pushing, from the docs... but is in the v1.0.0-beta.3 version
var pushData = {
posts: [
{id: 1, post_title: "Great post", comment_ids: [2]}
],
comments: [
{id: 2, comment_body: "Insightful comment"}
]
}
store.pushPayload('post', pushData);
In your case the call should be
#get('store').pushPayload('organization', data)
And the data json an array of organizations
organizations:[
{id:1,...},
{id:2,...},
{id:3,...}
]

Jtable options array for drop down list or select list

I've been trying to create an object to use in a jtable as the options (for a select list).
I don't seem to have the format correct. The jtable.org website says it will take an array:
From the jtable.org website:
http://jtable.org/ApiReference#fopt-options
PhoneType: {
title: 'Phone type',
options: [{ Value: '1', DisplayText: 'Home phone' }, { Value: '2', DisplayText: 'Office phone' }, { Value: '2', DisplayText: 'Cell phone' }]
}
However, when I create an object like that:
var optionsObject = [];
optionsObject.push({Value: i, DisplayText: 'Hello' + i});
and then use it as a variable for the options in my jtable:
key: true,
options: optionsObject,
I don't get the items in the select list drop down. I do get something in the select list, but that looks like '[object Object]' instead of the actual items.
I'm not really sure what I'm doing wrong.
If I send an object that looks like this:
object.push('hello' + i);
I will get an item in the select list that looks like this 'hello0', as expected, but then the display text is also used as the value. I need to have an object with separate display texts and values.
Has anybody had any success with doing this?
After much trial and error, and debugger stops in the jtable scripting files, I learned that in order to use an object for the 'options' property of a field in jtable, the object must be in the following format
var optionsObject = new Object();
optionsObject[Value] = DisplayText;

Ext.form.ComboBox: Use template for displayField

Is there any way to apply a template to the selected value of a ComboBox? I'm using a template to display the drop down values of the ComboBox, but as soon as i select one, the plain value from the datastore is shown.
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
tpl: '<tpl for="."><div class="x-combo-list-item">{statusCode:requestStatus}</div></tpl>',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.ArrayStore({
fields: ['statusCode'],
data: [['unassigned'],['assigned'],['closed']]
}),
valueField: 'statusCode',
displayField: 'statusCode'
}
I want to use my format function requestStatus to translate the statusCodes into locale spesific status names, and this works well for the drop down list, but as soon as I select something, the statusCode is shown.
So is it possible to assign a template to the displayField, or perhaps do some simple batch modification on the datastore? By processing the input through a reader maybe? Is there another <tpl for="?"> keyword that will make this happen?
I'm looking for some simple method utilizing the Ext library. If the only solution is to pre process the data, I'm capable of doing that myself.
I found a solution!
I changed my datastore, and added a reader to pre-process the status using a convert function:
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.Store({
data: [['unassigned'],['assigned'],['closed']],
reader: new Ext.data.ArrayReader({},[
{name: 'statusCode', mapping: 0},
{name: 'displayname', mapping: 0, convert: function(statusCode) {
return Ext.util.Format.requestStatus(statusCode);
}}
])
}),
valueField: 'statusCode',
displayField: 'displayname'
}
Examinig generated DOM you will notice that while list elements are DIVs, the field itself is html INPUT element. You can't have HTML within INPUT element... so no... no xtemplate here.
This does not mean it can't be done by extending Ext.form.ComboBox (or Ext.Component maybe)