Is setting a multiple mat-select dropdown value to objects possible? - angular-material

Using mat-select in multiple mode, is it possible to pre-set the selected values if the values that are part of the select options are objects?
For example if the options in the select are as follows
toppingList: any[] = [
{ id: 1, description: 'Extra cheese' },
{ id: 2, description: 'Mushroom' },
{ id: 3, description: 'Onion' },
{ id: 4, description: 'Pepperoni' },
{ id: 5, description: 'Sausage' },
{ id: 6, description: 'Tomato' }
];
Then can you pre-set the selected values for that mat-select as such?
this.toppings.setValue([{ id: 1, description: 'Extra Cheese' }]);
Taking this stackblitz as an example you see that the the form values are getting set as desired, but the select buttons in the drop down itself are not showing as checked.
Is this even possible, or am I doing something wrong?

as i know for equality of two object, for example in java, you need write equal / hashcode for detect what object equal to another one.
you bind select value to object and typescript could not understand what compare object together. so i change your sample and bind value of options to id and it works!
see this stackblits

Related

Updating Highcharts column chart based on drop down-menu

I'm trying to have Highcharts do the following: I want to show a column chart with three columns. The two first are to remain constant, the third is to be updated multiple times based on what the user chooses from a drop down-menu.
Choosing from the drop down-menu, I am able to have the third column update. If it's showing "Name 3" initially, choosing "Name 4" from the drop down menu will correctly replace the column. Choosing "Name 5" causes another correct replacement. However, if I then choose "Name 3" again, only the label will update, while the column and the y-value in the tooltip will not. Thus, it will say "Name 3", but use the y-value for "Name 5". How do I fix this behaviour?
The important thing here is user control of column 3. It would be okay to only show 2 column initially, if it's easier.
Code:
var data = {
"10 - Name 1": [700000],
"1001 - Name 2": [750000],
"1000 - Name 3": [800000],
"1002 - Name 4": [900000],
"1003 - Name 5": [950000]
};
var chart = Highcharts.chart('fig8', {
chart: {
type: 'column',
animation: true
},
series: [{
name: "10 - Name 1",
data: data["10 - Name 1"]
}, {
name: "1001 - Name 2",
data: data["1001 - Name 2"]
}, {
name: "1000 - Name 3",
data: data["1000 - Name 3"]
}],
title: {
text: 'Some metric'
},
subtitle: {
text: 'Choose unit from drop down to alter third column'
},
xAxis: {
labels: {
enabled: false
}
}
});
$("#sel").change(function() {
chart.series[2].update({
name: this.value,
data: data[this.value]
});
});
Here's a stripped down example: https://jsfiddle.net/RuneS/soh8vw79/10/
#jlbriggs is correct. Although the docs for update() don't say anything about it, it is mentioned in the docs for setData(): When updating series data, the default behavior is to update the values in the original data array instead of replacing the whole array.
In your case, that means that "Name 3"'s value is overwritten by the others' values when you select from the dropdown. There are at least two ways to fix this:
Force Highcharts to replace the data array by calling setData() with the updatePoints parameter instead of sending the data with update():
$("#sel").change(function() {
var unit = this.value,
val = data[unit],
ser = chart.series[2];
ser.update({ name: unit }, false);
//... false): Replace the series' data array instead of updating its values,
//(which would alter the original array in the global `data` object).
//https://api.highcharts.com/class-reference/Highcharts.Series#setData
ser.setData(val, true, true, false);
});
https://jsfiddle.net/soh8vw79/22
Don't give Highcharts the original array, but a copy of it. That way, updating the values won't affect the original data (similar to #jlbriggs solution). Added bonus: Smooth animation:
...
series: [{
name: "10 - Name 1",
data: data["10 - Name 1"]
}, {
name: "1001 - Name 2",
data: data["1001 - Name 2"]
}, {
name: "1000 - Name 3",
//Here, we use `.slice()` to make a copy of the original array,
//so that future updates don't change the original values in the global `data` object:
data: data["1000 - Name 3"].slice()
}],
...
https://jsfiddle.net/soh8vw79/23

array observable with content observable and jqAutocomplete

I'm using Knockout 3 with the plugin jqAutocomplete by Ryan Niemeyer. I have a problem with this model:
var ViewModel = function() {
var self = this;
self.myOptionsObs = ko.observableArray([
{ id: ko.observable(1), name: ko.observable("item 1 o"), description: ko.observable("item label 1 o") },
{ id: ko.observable(2), name: ko.observable("item 2 o"), description: ko.observable("item label 2 o") },
{ id: ko.observable(3), name: ko.observable("item 3 o"), description: ko.observable("item label 3 o") }
]);
self.myValueObs = ko.observable();
};
ko.applyBindings(new ViewModel());
<input data-bind="jqAuto: { source: myOptionsObs, value: myValueObs, inputProp: 'name', template: 'itemTmpl' }" />
As you can see, there is an observable array and each element is also an observable.
The autocomplete don't work well. As you can see in this Fiddle, the left column has an observable array but its elements aren't observable. If you click in the left box and write something, a list of options appear.
But in the right column, you have the same, but the element's are all observable. If you click in the right box and write something, when the list appear, if you move the cursor up and down, you could see that the row 'name' gets deleted and filled with zeros.
What I have to change in my data-bind attribute?
This question is related with this question.
I have to say that this solution works ok for me. But the updated plugin don't.
Thanks !!
The jqAutoComplete plugin isn't setup to work with observable properties (although it could be enhanced to do so without much work).
For now, I think that your best bet is to create a computed that will always return a plain and up-to-date version of your options.
self.myOptionsObs.plain = ko.computed(function() {
return ko.toJS(self.myOptionsObs);
});
Sample: http://jsfiddle.net/rniemeyer/45cepL9b/
I'll try to take a look at some point about supporting observable properties. Shouldn't take many changes.

How to structure falcor router to get all available IDs?

I'm experimenting with using Falcor to front the Guild Wars 2 API and want to use it to show game item details. I'm especially interested in building a router that can use multiple datasources to combine the results of different APIs.
The catch is, Item IDs in Guild Wars 2 aren't contiguous. Here's an example:
[
1,
2,
6,
11,
24,
56,
...
]
So I can't just write paths on the client like items[100..120].name because there's almost certainly going to be a bunch of holes in that list.
I've tried adding a route to my router so I can just request items, but that sends it into an infinite loop on the client. You can see that attempt on GitHub.
Any pointers on the correct way to structure this? As I think about it more maybe I want item.id instead?
You shouldn't find your self asking for ids from a Falcor JSON Graph object.
It seems like you want to build an array of game ids:
{
games: [
{ $type: "ref", value: ["gamesById", 352] },
{ $type: "ref", value: ["gamesById", 428] }
// ...
],
gamesById: {
352: {
gameProp1: ...,
},
428: {
gameProp2: ...
}
}
}
[games, {from: 5, to: 17 }, "gameProp1"]
Does that work?
You can use 'get' API of Falcor, It retrieves multiple values.. You can pass any number of required properties as shown below
var model=new falcor.Model({
cache:{
genereList:[
{name:"Recently Watched",
titles:[
{id:123,
name: "Ignatius",
rating: 4}
]
},
{name:"New Release",
titles:[
{id:124,
name: "Jessy",
rating: 3}
]
}
]
}
});
Getting single value
model.getValue('genereList[0].titles[0].name').
then(function(value){
console.log(value);
});
Getting multiple values
model.get('genereList[0..1].titles[0].name', 'genereList[0..1].titles[0].rating').
then(function(json){
console.log(JSON.stringify(json, null, 4));
})

Use an array of objects for series data in Highcharts

I have an array of objects that I want to display in highcharts. Every object has a name and a value.
I have tried to get this to work by doing
var objects = objectArray[]; // objectArray being an array of the objects I want data on
var objectNames = nameArray[]; // This being an array of all the names of the objects
var objectValues = valueArray[]; // An array of all the values of the objects
series: [{
data: objects.value,
name: objects.name
}]
This blew up on me. So I tried building the series like this:
series: [{
data: objectValues,
name: objectNames
}]
This gave me data for the values, but the name was all of the names in the objectNames array... for every single piece of data. so I tried using
series: [{
data: objectValues
},
{
data: objectNames
}]
This resulted in seeing the chart for the objectValues, and in the legend, another option for the names - which is completely unacceptable because there's no point in having a series of labels, right?
So I decided I would programmatically build out a series, using a foreach loop and then pass that into the constructor. However, http://www.highcharts.com/docs/getting-started/how-to-set-options/ says this is "bad code".
What I'm wanting is to be able to pass an array of objects to highcharts, tell it that every piece of data's 'name' is going to be the name value on that particular object, and the data is going to be tied to that particular object's value field. Is there a way to do this? Or is the only option what highcharts considers 'bad'?
So I found a solution.
After getting the data, I did
$.each(item, function (index, value) {
objects.push([value.name, value.value]);
});
And then bound my series with
series: [{
data: objects,
name: 'Value Type Description'
}]
So I have "Value Type Description" in the legend, but when I hover over a specific point I have the name as the label, and valid data displaying in graph form.
I found at http://api.highcharts.com/highcharts#series that if you have an array of two dimensional arrays, you can just pass a string as the first parameter and it would parse it as the label for that point.
EDIT: Example per request.
So you have two pieces to the series field, data and name. Name does NOT apply to the data, that will be the name of the axis.
So data is an array of key/value pairs.
data: [
{[key1, value1]},
{[key2, value2]},
{[key3, value3]}
]
And name is what the "main" label will be - "My Data Stuff" for example.
Then, when you load the chart, in the legend it should say "My Data Stuff", but when you hover over a specific point, say the first one, it will display the Key1 Value1 information.
data: [{
name: 'Point 1',
y: 1,
test1:9,
test2:'ddaf'
}, { -------> right
name: 'Point 2',
y: 5,
test1:12,
test2:'ddddaf'
}]
data: [{
my_name: 'Point 1',
y: 1,
test1:9,
test2:'ddaf'
}, { -------> we change 'name' to 'my_name',
my_name: 'Point 2', then the name you want to show become
y: 5, 'Slice', instead of 'Point 1','Point 2'
test1:12,
test2:'ddddaf'
}]
data: [{
my_name: 'Point 1',
my_y: 1,
test1:9,
test2:'ddaf'
}, { -------> Now,we get nothing.
my_name: 'Point 2',
my_y: 5,
test1:12,
test2:'ddddaf'
}]
So,the 'name' and 'y' is the key.

Accessing next Elements Name in Highcharts Tooltip

How can we get next elements name in Highcharts
for example
series: [{ name: 'weight', data: [50, 48, 80, 70]},
{ name: 'height',data: [5.8, 5.1, 6.1, 6.0]}
]
tooltip: {
formatter: function(){
return this.series.name;//i want to return here next elements name also is there any way
}
}
in the above tooltip iam returning only current element name, is there any way to get immediate next elements name there..?
You can always use shared tooltip, take a look: http://api.highcharts.com/highcharts#tooltip.shared

Resources