Jan Horčička
Jan Horčička

Reputation: 853

Different typeof result on the same object

I am getting some data from S3 using AWS SDK. The response I am getting is this:

{
...
,
    "Contents": [
        {
            "Key": "data copy.csv",
            "LastModified": "2021-02-19T11:16:24.000Z",
            "ETag": "\"69d6972deead4b9a378473654c878d75\"",
            "Size": 305,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "data.csv",
            "LastModified": "2021-02-19T11:16:24.000Z",
            "ETag": "\"69d6972deead4b9a378473654c878d75\"",
            "Size": 305,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "folder1/",
            "LastModified": "2021-02-19T11:16:12.000Z",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 0,
            "StorageClass": "STANDARD"
        },
        {
            "Key": "folder2/",
            "LastModified": "2021-02-19T11:16:16.000Z",
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 0,
            "StorageClass": "STANDARD"
        }
    ],
...
}

When I loop through the properties of one of the Contents items using this code, I can see that type of each of the items is "string":

for (const property in Contents[0]) {
   console.log(`Type of ${property}: ${typeof property}`);
}

outputs:

Type of Key: string
Type of LastModified: string
Type of ETag: string
Type of Size: string
Type of StorageClass: string

I want to sort the items by their date - "LastModified". The problem is that when I ask for the type of "LastModified", the output is "object".

console.log(typeof Contents[0].LastModified); // object
console.log(typeof Contents[0]['LastModified']); // object

Since it's an object, I cannot compare using String comparison. So my questions are:

  1. Why does one method say it's a "string" and another one says it's an "object"?
  2. What is the best way to convert it to a string (or a date) so I can compare the items?

Upvotes: 1

Views: 49

Answers (3)

hackape
hackape

Reputation: 19947

Each item in Contents array is an object of key-value pairs. First method you check typeof the “key” (the property in your code), while second method you check against the “value”. No wonder they say different things.

AWS SDK deserializes/revives those content items into native JS object. It turn the string representation of date into a JS Date instance, that why typeof check says "object". If you check instanceof Contents[0].LastModified === Date it will say true.

To sort items by date, best practice is to convert date value into number, value of which is integer that represents unix timestamp in milliseconds. Example:

Contents.sort((a, b) => Number(a.LastModified) - Number(b.LastModified))

Upvotes: 1

neilnikkunilesh
neilnikkunilesh

Reputation: 383

Note that if your dates are in string format, you first need to parse them to Date

sort an object array by date property?

array.sort(function(a,b){
// Turn your strings into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(b.date) - new Date(a.date);
});

For your code array will be replaced with Contents[0]

Upvotes: 1

Ben Taber
Ben Taber

Reputation: 6731

for (const property in Contents[0]) {
   console.log(`Type of ${property}: ${typeof property}`);
}

The property key is a string. You're testing typeof of the property key, not the property value.

Typeof the property value would be

for (const property in Contents[0]) {
   console.log(`Type of ${property}: ${typeof Contents[0][property]}`);
}
  1. It most likely has already been converted to a native Date object by the AWS SDK. For comparison, use Contents[0].LastModified.getTime() to return the UNIX epoch timestamp (in milliseconds).

Upvotes: 1

Related Questions