JavaScript Object Items Order
Patrik Braborec
Posted on August 19, 2020
The Bug 🐛
I had to solve an issue with the order of items in a dropdown. The problem was that items in the dropdown were sorted wrongly (in a different way than from the server).
For example, data from the server were in this order:
const items = [{
id: "/product/id/2",
title: "product 2"
},
{
id: "/product/id/1",
title: "product 1"
},
{
id: "/product/id/4",
title: "product 4"
},
{
id: "/product/id/5",
title: "product 5"
},
];
There was a function which mapped that data from the server into an object, something like this:
function mapToObject(items) {
return items.reduce((acc, item) => {
acc[item.id] = item;
return acc;
}, {});
};
Because JavaScript (for objects) does not (always) follow the insertion order, the result of that function was:
{
"/product/id/1": {
id: "/product/id/1",
title: "product 1"
},
"/product/id/2": {
id: "/product/id/2",
title: "product 2"
},
"/product/id/4": {
id: "/product/id/4",
title: "product 4"
},
"/product/id/5": {
id: "/product/id/5",
title: "product 5"
}
}
The result of that function led to the wrong order of items in the dropdown.
Why does it happen? 🔍
Property order in normal Objects is a complex subject in JavaScript.
While in ES5 explicitly no order has been specified, ES2015 defined an order in certain cases, and successive changes to the specification since have increasingly defined the order (even, as of ES2020, the for-in
loop's order). Given is the…
The Solution 🚀
I wanted to keep "similar structure" because the dropdown can have a lot of items (for example, I would have to iterate over all items to get a selected item) so I solved the issue with a Map object - guarantees the keys will be iterated in order of insertion and it has similar features like Object.
function toMappedItems(items) {
const map = new Map();
items.forEach(item => map.set(item.id, item));
return map;
}
The result of that new function is:
0: {"/product/id/2" => {id: "/product/id/2", ...}}
1: {"/product/id/1" => {id: "/product/id/1", ...}}
2: {"/product/id/4" => {id: "/product/id/4", ...}}
3: {"/product/id/5" => {id: "/product/id/5", ...}}
So it is easy to work with that result and it keeps the order of items from the server.
The whole problem and solution are "simplified". The main take away is to not rely on the order in Object. 🎉
Posted on August 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024