-2

I have an object like this:

{
   name: 'ABC',
   age: 12,
   timing: '2021-12-30T11:12:34.033Z'
}

I want to make array of object of each key of above object like this:

[
   {
      fieldName: 'name',
      dataType: 'string'
   },
   {
      fieldName: 'age',
      dataType: 'number'
   },
   {
      fieldName: 'timing',
      dataType: 'date'
   }
]

I tried this:

let op = Object.entries(data).map(([key, value]) => ({
            fieldName: key,
            dataType: typeof value
        }));

but getting dataType: 'object' for date column but not able to achieve it. Is there any solution? Thanks in advance.

techguy
  • 71
  • 8
  • 1
    [`Object.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)? – evolutionxbox Jan 27 '22 at 08:35
  • @evolutionxbox yah it's working with it. but not able to do it for dataType key, because it is not working for date type – techguy Jan 27 '22 at 08:41
  • Declare your Object like this `{ fieldName: key, dataType: typeof value}` – SaschaLeh Jan 27 '22 at 08:47
  • @SaschaLeh I did the same thing, but I got result as "object" for date column – techguy Jan 27 '22 at 08:49
  • As a eager as I am too to close this question, I'm voting to re-open citing OPs last comment. There is a special case where the string `date` has to be used if the value of the property is a valid time stamp. – ruth Jan 27 '22 at 08:51
  • do you have always an iso date string as date type? – Nina Scholz Jan 27 '22 at 09:29

5 Answers5

1

You can use date parse to check is a valid date or not.

const input = {
  name: 'ABC',
  age: 12,
  timing: '2021-12-30T11:12:34.033Z'
};

const output = Object.entries(input).map(([key, value]) => ({
  fieldName: key,
  dataType: typeof value === 'string' && !isNaN(Date.parse(value)) ?  'date':typeof value
}));

console.log(output);
Rahul Sharma
  • 9,534
  • 1
  • 15
  • 37
0

You could use Object#entries with Array#map and typeof to the get the type of the value. For the case where 'date' must be used for valid time stamps, you could use Date.parse() method with Number#isNaN.

Try the following

const input = {
  name: 'ABC',
  age: 12,
  timing: '2021-12-30T11:12:34.033Z'
};

const output = Object.entries(input).map(([key, value]) => ({
  fieldName: key,
  dataType: typeof value !== 'string' || isNaN(Date.parse(value)) ? typeof value : 'date'
}));

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Edit: Replace Object#values with Object#entries.

Edit 2: Add typeof value !== 'string' for dataType condition. Borrowed from @RahulSharma's answer.

ruth
  • 29,535
  • 4
  • 30
  • 57
  • getting error: Argument of type 'unknown' is not assignable to parameter of type 'string' – techguy Jan 27 '22 at 08:54
  • @techguy: Update the question with your attempt. Obviously there is an error in the types you're using. – ruth Jan 27 '22 at 08:55
  • now it's not working with numbers, it showing 'date' for number columns as well – techguy Jan 27 '22 at 09:00
  • for age column also it showing 'date' – techguy Jan 27 '22 at 09:09
  • @techguy: Please see [here](https://stackoverflow.com/a/56487020/6513921) for the `unknown` error. TL;DR: Try to define a type for the input. If you get the "_Type `'number'` is not assignable to type `'string'`_" error for `Date.parse()`, include a type check for `'string'` as shown by @RahulSharma in his answer. – ruth Jan 27 '22 at 09:10
  • @techguy: The solution is working in the inline code. If you get `'date'` for all the properties of the object, please try to create a reproducible example. – ruth Jan 27 '22 at 09:11
  • you can see your own example's output by clicking on button "Run code snippet", for age column it is 'date' – techguy Jan 27 '22 at 09:12
  • Unfortunately we're still running into browser issues. It's returning `'number'` in Firefox, and `'date'` in Chrome. I'll update the post to borrow from @RahulSharma's answer. – ruth Jan 27 '22 at 09:14
0

You can use Object.keys() and Array.prototype.map():

const ip = {
  name: 'ABC',
  age: 12,
  timing: '2021-12-30T11:12:34.033Z'
};

const op = Object.keys(ip).map((key) => ({
  fieldName: key,
  dataType: typeof ip[key] === 'string' && !isNaN(Date.parse(ip[key])) ? 'date' : typeof ip[key]
}));

console.log(op);
Kien Nguyen
  • 2,616
  • 2
  • 7
  • 24
0

Your solution looks fine, you just need to distinguish between normal string and a valid date string.

For this, I would recommend using dayjs package.

import dayjs from "dayjs";

const input = {
  name: "ABC",
  age: 12,
  timing: "2021-12-30T11:12:34.033Z"
};

const output = Object.entries(input).map(([key, value]) => {
  return {
    fieldName: key,
    dataType:
      typeof value === "string"
        ? dayjs(value).isValid()
          ? "date"
          : "string"
        : typeof value
  };
});

console.log("output", output);

CodeSandbox

If you want to reinvent the wheel and write a date checking function yourself, then take a look here for a few suggestions.

Cuong Vu
  • 3,423
  • 14
  • 16
0
Object.entries(a).map(([key, value]) => (
{
    fieldName: key,
    dataType: isNaN(value) && !isNaN(Date.parse(value)) ? 'date' : typeof(value) 
}))

But be careful with this as it will return for invalid dates in February, rg: 2013-02-31

With the date checking, you may should use some libraries such as Momentjs, . .

Phong Cao
  • 33
  • 3