0

I'm trying to reorder the items in an object so they will match the order of an array. The object is the row data and the array is the column names.

Here are the order of column names I want to match:

columnNames    [
    "System.Id",
    "System.WorkItemType",
    "System.Title",
    "System.AssignedTo",
    "System.State",
    "Microsoft.VSTS.Common.ActivatedDate",
    "System.ChangedDate",
    "Microsoft.VSTS.Common.ClosedDate"
    ]

Here is an example of the object items I'm trying to reorder:

 fields = {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}

Ultimately I just want the values of each item in the object placed in an array which matches the order of the columnNames array, so like this:

rowArray = [
7993,"Task","Update Dev Environment","Jack Smith","Closed","2022-07-19T12:14:25.193Z","2022-07-19T12:13:49.713Z","2022-07-19T12:14:25.193Z"]

I get the fields object from calling an API. In order to get only the fields I want I loop through part of the API response.

Here's my entire code if it helps to see what I'm trying to do:

queryItems = result from API call

queryItems.forEach((item) => {
        let sortingfields = [];
        let sortedfields = [];
        let rowArray = [];

        //loop through fields part of each response item and add it to new array sortingfields
        Object.entries(item.fields).forEach(([key, value]) => {
            switch(key){
                case 'System.AssignedTo':
                    sortingfields.push(key, item.fields[key].displayName);
                    break;
                case 'System.ChangedDate':
                    const changedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, changedDate);
                    break;
                case 'Microsoft.VSTS.Common.ActivatedDate':
                    const activatedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, activatedDate);
                    break;
                case 'Microsoft.VSTS.Common.ClosedDate':
                    const closedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, closedDate);
                    break;
                default:
                    sortingfields.push(key, item.fields[key]);
                    break;
            }
        })
        // sort array items so they match the order of the columnNames array
        sortedfields = sortingfields.sort((entryA, entryB) => {
            const [keyA] = entryA;
            const [keyB] = entryB;
            return columnNames.indexOf(keyA) - columnNames.indexOf(keyB)
        })
        // loop through sorted array and retrieve only the values
        for (let s of sortedfields){
            rowArray.push(sortedfields[s]);
        }
        // add array as a new row to Excel file using ExcelJS
        let row = sheet.addRow(rowArray);

    })

Now the error I get is Failure Exception: entryA is not iterable. I don't understand why given sortingfields is an array.

mdailey77
  • 1,673
  • 4
  • 26
  • 52
  • Does this answer your question? [How to change the order of a JavaScript object?](https://stackoverflow.com/questions/13618515/how-to-change-the-order-of-a-javascript-object) JS Objects are unordered, so you'll need to create a new object and add the keys/values in a loop, not with a sort function. – WOUNDEDStevenJones Jul 29 '22 at 16:21
  • An object is a key-value-pair collection and therefor an order doesn't make much sense - which is why they have a defined "order" only recently. If you need them to be in a specific order then iterate over the array and use these values to access the properties in the object. – Andreas Jul 29 '22 at 16:24
  • I didn't find that post helpful. – mdailey77 Jul 29 '22 at 20:01

2 Answers2

0

you can use map for that

you just map over the keys you want and get it from the object like this

const orderData = (data, order) => order.map(k => data[k]) 



const columnNames   =  [
    "System.Id",
    "System.WorkItemType",
    "System.Title",
    "System.AssignedTo",
    "System.State",
    "Microsoft.VSTS.Common.ActivatedDate",
    "System.ChangedDate",
    "Microsoft.VSTS.Common.ClosedDate"
    ]

const single = {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}
    
const data = [{"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}, {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}]


console.log(orderData(single, columnNames))

console.log(data.map(d => orderData(d, columnNames)))
R4ncid
  • 6,944
  • 1
  • 4
  • 18
  • Thanks so much. I had to rework some of my code to get your solution to work but it works now. The key value pairs are in the right order. – mdailey77 Jul 30 '22 at 22:07
0

I'm not really sure of what you want to achieve but here is my answer:

const fieldEntries = Object.entries(fields);
const entriesResult = fieldEntries.sort((entryA, entryB) => {
  const [keyA] = entryA;
  const [keyB] = entryB;
  return columnNames.indexOf(keyA) - columnNames.indexOf(keyB)
})
const objResult = Object.fromEntries(entriesResult)

This gives the following value for objResult:

{
System.Id:7993
System.WorkItemType:"Task"
System.Title:"Update Dev Environment"
System.AssignedTo:"Jack Smith"
System.State:"Closed"
Microsoft.VSTS.Common.ActivatedDate:"2022-07-19T12:13:49.713Z"
System.ChangedDate:"2022-07-19T12:14:25.193Z"
Microsoft.VSTS.Common.ClosedDate:"2022-07-19T12:14:25.193Z"
}

Sandbox: https://playcode.io/932608