0

I have a Spring Boot application with some endpoint that returns a map of items in JSON.

The map consists of bank account statement items grouped by date. The date is key (formated date string) and list of statement items - is a value:

Map<String, List<StatementItem>

Key sorting is always done by date (NOT ALPHABETICALLY), e.g:

{
    "Today": [...],
    "Yesterday": [...],
    "9 Jun 2021": [...],
    "8 Jun 2021": [...],
    "7 Jun 2021": [...],
    "6 Jun 2021": [...]
    ....
}

The problem is the Angular application that calls that endpoint is not able to handle the response and process obtained map with the same sorting. Keys are sorted alphabetically in the resulting map instead of original sorting from the backend.

HTTP call example:

this.httpClient.get<Map<string, StatementItem[]>>(`some request URL`);

And how the Angular parses map: enter image description here

Is there any way to "ask" Angular/TypeScript to parse JSON map as is, as it was obtained from the backend?

Vitalii
  • 383
  • 1
  • 2
  • 8

2 Answers2

2

As answered here Is the order of elements in a JSON list preserved?

  • An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
  • An array is an ordered sequence of zero or more values.

So this is how JSON generally works, not related specifically to Angular, Typescript, or Spring.

Amr Salama
  • 802
  • 1
  • 7
  • 19
1

This will create a new object for you to use with the time in milliseconds as the key. The previous key (a date) and it's actual date object are appended to the object as date and formatted_date so you can sort per usual

const data = {
  'Today': {
    foo: 'bar'
  },
  'Tomorrow': {
    foo: 'bar'
  },
  '4 June 2010': {
    foo: 'bar'
  },
  '12 Dec 2025': {
    foo: 'bar'
  }
}

let ndata = {}
for (const [key, obj] of Object.entries(data)) {
  let fkey = new Date(key)
  switch (key.toLowerCase()) {
    case 'today':
      fkey = new Date();
      break;
    case 'tomorrow':
      let tomorrow = new Date();
      tomorrow.setDate(tomorrow.getDate() + 1);
      fkey = tomorrow
      break;
  }
  obj.date = key;
  obj.formatted_date = fkey
  ndata[fkey.getTime()] = obj;
}

console.log('Unsorted, raw:', ndata)

// if you need to sort it manually

const sortObj = obj => {
  return Object.keys(obj).sort().reduce(function(result, key) {
    result[key] = obj[key];
    return result;
  }, {});
}

ndata = sortObj(ndata);

console.log('Sorted:', ndata)
Kinglish
  • 23,358
  • 3
  • 22
  • 43