How can we use the dataKey when setting the value of a dropdown? I have:
<p-dropdown [options]="animeDS" formControlName="anime" placeholder="Select a anime*" optionLabel="code" [autoWidth]="false" [dataKey]="id" [filter]="true"></p-dropdown>
Which is a filter, generated from one datasource which only returns id and code. And then another which is a part of an entity let's say animeShow, which has more anime fields, for example: id, code, description, date_shown, etc. When I try to set the dropdown from this value it fail, because it compares via string comparison. I would like to use the dataKey so whatever fields are added / removed the comparison will not be affected.
Use dataKey to compare item in a Dropdown
Linkedin: https://www.linkedin.com/in/czetsuya
Blog: https://czetsuya-tech.blogspot.com
Github: https://github.com/czetsuya
Blog: https://czetsuya-tech.blogspot.com
Github: https://github.com/czetsuya
I don't think this feature works for p-dropDown.
I have been trying to figure it out, but the documentation is sparse, and I was unable to find any working examples online.
Strange, as it's not that uncommon to bind a complex object array to the [options] attribute and have the selection bind to a specific member of the object such as an ID field, especially since there is an optionLabel attribute which seems to work fine.
Would love to see a more concrete implementation such as an optionValue attribute. Not being able to bind the value to a member of the selected option is kind of limiting.
If anyone can post a working snippet, I would definitely appreciate it.
I have been trying to figure it out, but the documentation is sparse, and I was unable to find any working examples online.
Strange, as it's not that uncommon to bind a complex object array to the [options] attribute and have the selection bind to a specific member of the object such as an ID field, especially since there is an optionLabel attribute which seems to work fine.
Would love to see a more concrete implementation such as an optionValue attribute. Not being able to bind the value to a member of the selected option is kind of limiting.
If anyone can post a working snippet, I would definitely appreciate it.
This drives me mad.
So, value is string value of 1.
Options:
Set the dataKey to "id", ngModel is a value of "1"...
Then this comes along and makes me want to burn a book.
objectutils.ts
Issue is that now in the first pass, data is "1" with a field of "id" BUT when it passes the next check to see if the selectedItem should be set when calling;
dropdown.ts
Issue.... val = "1", opts[0].value = { "id": 1, "description": "item1" }, dataKey = "id"
can you see who this WILL NOT equal and fail every damn time?! So, I set val to be { "id": 1 } cause that should mean data[field] should return 1... BUT NO I need the full object of { "id": 1, "description": "item1" } (MAKES COMPLETE SENSE DO NOT GET ME WRONG, BUT, BUT, I will not store that object JUST THE VALUE OF ID!) but by GOD 4 hours of my life wasted.
This is way over complicated to understand yourself when you want to use dataKey when you cannot re-write your entire backend to use label and value items in lists.
So, because there is NOTHING to help with understanding the dataKey, here it is.
If using dataKey set this to be the key value of which you are storing, i.e. if you have { "id": 1 } then set the dataKey to be "id".
Now, the ngModel connection or even formControl must match the item in the list, so if you have options like above in the first code block the selected item must match this, so if you only get the id from the database you will have to filter your list to a selected item and THEN make sure you flip this back when talking to the server.
So, when you adding this to the docs?! Can you understand why I'm unhappy about this?! Had to debug to understand the code, because! there is nothing to say how this works.
So, value is string value of 1.
Options:
Code: Select all
[{ "id": 1, "description": "item1" }, { "id": 2, "description": "item2" }]
Then this comes along and makes me want to burn a book.
objectutils.ts
Code: Select all
public resolveFieldData(data: any, field: any): any {
if(data && field) {
if (this.isFunction(field)) {
return field(data);
}
else if(field.indexOf('.') == -1) {
return data[field];
}
else {
let fields: string[] = field.split('.');
let value = data;
for(let i = 0, len = fields.length; i < len; ++i) {
if (value == null) {
return null;
}
value = value[fields[i]];
}
return value;
}
}
else {
return null;
}
}
dropdown.ts
Code: Select all
findOptionIndex(val: any, opts: any[]): number {
let index: number = -1;
if(opts) {
for(let i = 0; i < opts.length; i++) {
if((val == null && opts[i].value == null) || this.objectUtils.equals(val, opts[i].value, this.dataKey)) {
index = i;
break;
}
}
}
return index;
}
can you see who this WILL NOT equal and fail every damn time?! So, I set val to be { "id": 1 } cause that should mean data[field] should return 1... BUT NO I need the full object of { "id": 1, "description": "item1" } (MAKES COMPLETE SENSE DO NOT GET ME WRONG, BUT, BUT, I will not store that object JUST THE VALUE OF ID!) but by GOD 4 hours of my life wasted.
This is way over complicated to understand yourself when you want to use dataKey when you cannot re-write your entire backend to use label and value items in lists.
So, because there is NOTHING to help with understanding the dataKey, here it is.
If using dataKey set this to be the key value of which you are storing, i.e. if you have { "id": 1 } then set the dataKey to be "id".
Now, the ngModel connection or even formControl must match the item in the list, so if you have options like above in the first code block the selected item must match this, so if you only get the id from the database you will have to filter your list to a selected item and THEN make sure you flip this back when talking to the server.
Code: Select all
items: List[] = [];
selectedItem: List = new List();
selectedValue = '2';
someSetListFunc() {
someHttpGetProcess().sub(response => {
this.items = response.data;
this.selectedItem = this.items.filter(x => x.id === this.selectedValue)[0];
});
}
someSendToServer() {
myServerObject: Server = new Server();
myServerObject.someId = this.selectedItem.id;
}
// <p-dropdown [options]="items" [(ngModel)]="selectedItem" dataKey="id" optionalLabel="description"></p-dropdown>
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live - John Woods
-
- Posts: 1
- Joined: 15 Jul 2020, 13:41
Agreed with the frustration that OP described. I've wasted hours dealing with this. A custom comparison function would solve a lot of the issues.
As mentioned, the issue with DataKey stems from a bug in, which will always return undefined when using DataKey. DataKey forces the "obj2" to be a primitive value, despite the dropdown values being objects. So even if your select item is an object, then the resolveFieldData comparison will fail!
The simple fix to this is to add a check to the beginning of resolveFieldData for whether or not the data is actually an object; if it isn't just return data:
This makes sense because resolveFieldData is attempting to get a property value in some objects.
As mentioned, the issue with DataKey stems from a bug in
Code: Select all
resolveFieldData
The simple fix to this is to add a check to the beginning of resolveFieldData for whether or not the data is actually an object; if it isn't just return data:
Code: Select all
static resolveFieldData(data, field) {
if (typeof(data) !== 'object') return data;
if (data && field) {
if (this.isFunction(field)) {
return field(data);
}
else if (field.indexOf('.') == -1) {
return data[field];
}
else {
let fields = field.split('.');
let value = data;
for (let i = 0, len = fields.length; i < len; ++i) {
if (value == null) {
return null;
}
value = value[fields[i]];
}
return value;
}
}
else {
return null;
}
}
Hi,
I had the same issue and was stuck for the better part of my workday...This implementation is stupid, to say the least. I later went with the option to filter the array of object which I set as dropdown values from the values I get as set values from DB.
I had the same issue and was stuck for the better part of my workday...This implementation is stupid, to say the least. I later went with the option to filter the array of object which I set as dropdown values from the values I get as set values from DB.
-
- Information
-
Who is online
Users browsing this forum: Google [Bot] and 21 guests