简体   繁体   中英

Object.entries and flatMap handle null value

So i have an function to transform data but the problem is when it comes to null value the Object.entries and flatMap it show an error like this, which it cannot read the null object or undefined object:

    Object.entries(val).map(([k, v]) => [key + '_' + k, v]) : 
             ^

TypeError: Cannot convert undefined or null to object
    at Function.entries (<anonymous>)
    at Function.<anonymous> (/tmp/puFsbRMXEh.js:6:14)
    at Array.flatMap (<anonymous>)
    at /tmp/puFsbRMXEh.js:3:24
    at Array.map (<anonymous>)
    at transform (/tmp/puFsbRMXEh.js:1:32)
    at Object.<anonymous> (/tmp/puFsbRMXEh.js:95:13)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)

here is my code:

const transform = data => data.map(el =>
  Object.fromEntries(
    Object.entries(el).flatMap(
        
      ([key, val]) => val === null ? 
      Object.entries(val).map(([k, v]) => [key + '_' + k, v]) : 
      [[key, val]] ,
    ([key, val]) => val && typeof val === 'object' ? 
      Object.entries(val).map(([k, v]) => [key + '_' + k, v]) : 
      [[key, val]],
      )
    )
  )




const data = [{
    id: '6397f6f46b18bc89cb37053c',
    cost_center: null,
    plant: null,
    material: null
  },
  {
    id: '6397f7166b18bc89cb372ff7',
    cost_center: 'C118as0008',
    short_description: 'LINE PasdNG ALL',
    plant: 'K1as8',
    material: '300006',
    material_name: 'DRILLO PBJ 22g MT (12 pcs x 8 ib)',
    base_quantity: 218.995,
    ZAP_DP: {
      acttyp: 'ZAP_DP',
      stdval: 0.224,
      unit: 'HR'
    },
    ZAP_EL: {
      acttyp: 'ZAP_EL',
      stdval: 0.224,
      unit: 'HR'
    },
    ZAP_LH: {
      acttyp: 'ZAP_LH',
      stdval: 0.224,
      unit: 'HR'
    },
    ZAP_OT: {
      acttyp: 'ZAP_OT',
      stdval: 0.224,
      unit: 'HR'
    },
    kwh: 35.46,
    no_mc_mmbtu: 5,
    noempl: 50
  },
  {
    id: '6397f7166b18bc89cb373003',
    cost_center: 'C11asd9',
    short_description: 'LINE WAasdAT FOX',
    plant: 'K1aas8',
    material: '300007',
    material_name: 'asBAasd0g GT (60 pcs)',
    base_quantity: 28.816,
    ZAP_DP: {
      acttyp: 'ZAP_DP',
      stdval: 0.33,
      unit: 'HR'
    },
    ZAP_EL: {
      acttyp: 'ZAP_EL',
      stdval: 0.33,
      unit: 'HR'
    },
    ZAP_GS: {
      acttyp: 'ZAP_GS',
      stdval: 0.33,
      unit: 'HR'
    },
    ZAP_LH: {
      acttyp: 'ZAP_LH',
      stdval: 0.33,
      unit: 'HR'
    },
    ZAP_OT: {
      acttyp: 'ZAP_OT',
      stdval: 0.33,
      unit: 'HR'
    },
    kwh: 72.67,
    no_mc_mmbtu: 1.85,
    noempl: 14.5
  }
]

console.log(transform(data))

Is that possible to change the null value into this, or can someone pointed out where did i do wrong here?

[
  {
    "id": "6397f6f46b18bc89cb37053c",
    "cost_center": "",
    "plant": "",
    "material": ""
  },
  {
    "id": "6397f7166b18bc89cb372ff7",
    "cost_center": "C118as0008",
    "short_description": "LINE PasdNG ALL",
    "plant": "K1as8",
    "material": "300006",
    "material_name": "DRILLO PBJ 22g MT (12 pcs x 8 ib)",
    "base_quantity": 218.995,
    "ZAP_DP_acttyp": "ZAP_DP",
    "ZAP_DP_stdval": 0.224,
    "ZAP_DP_unit": "HR",
    "ZAP_EL_acttyp": "ZAP_EL",
    "ZAP_EL_stdval": 0.224,
    "ZAP_EL_unit": "HR",
    "ZAP_LH_acttyp": "ZAP_LH",
    "ZAP_LH_stdval": 0.224,
    "ZAP_LH_unit": "HR",
    "ZAP_OT_acttyp": "ZAP_OT",
    "ZAP_OT_stdval": 0.224,
    "ZAP_OT_unit": "HR",
    "kwh": 35.46,
    "no_mc_mmbtu": 5,
    "noempl": 50
  },
...]

Passing two callback functions to .flatMap() makes little sense. The first argument for .flatMap() should be the callback, and the second argument is the thisArg which specifies what this is inside of the callback function (which is not useful when the callback argument is an arrow function).

Instead, just use the second callback function you have (as this contains the most correct code), and convert the values to "" if they are null when mapping your entries. Below I've made a helper function that checks if the value is null and if it is, it returns "" , otherwise it returns the curren value. I've used this helper function when flattening the inner objects as well as when mapping the standard keys:

 const transform = data => data.map(el => Object.fromEntries( Object.entries(el).flatMap( ([key, val]) => val && typeof val === 'object'? Object.entries(val).map(([k, v]) => [key + '_' + k, nullToStr(v)]): [[key, nullToStr(val)]] ) ) ); const nullToStr = (v) => v === null? "": v; const data = [{ id: '6397f6f46b18bc89cb37053c', cost_center: null, plant: null, material: null }, { id: '6397f7166b18bc89cb372ff7', cost_center: 'C118as0008', short_description: 'LINE PasdNG ALL', plant: 'K1as8', material: '300006', material_name: 'DRILLO PBJ 22g MT (12 pcs x 8 ib)', base_quantity: 218.995, ZAP_DP: { acttyp: 'ZAP_DP', stdval: 0.224, unit: 'HR' }, ZAP_EL: { acttyp: 'ZAP_EL', stdval: 0.224, unit: 'HR' }, ZAP_LH: { acttyp: 'ZAP_LH', stdval: 0.224, unit: 'HR' }, ZAP_OT: { acttyp: 'ZAP_OT', stdval: 0.224, unit: 'HR' }, kwh: 35.46, no_mc_mmbtu: 5, noempl: 50 }, { id: '6397f7166b18bc89cb373003', cost_center: 'C11asd9', short_description: 'LINE WAasdAT FOX', plant: 'K1aas8', material: '300007', material_name: 'asBAasd0g GT (60 pcs)', base_quantity: 28.816, ZAP_DP: { acttyp: 'ZAP_DP', stdval: 0.33, unit: 'HR' }, ZAP_EL: { acttyp: 'ZAP_EL', stdval: 0.33, unit: 'HR' }, ZAP_GS: { acttyp: 'ZAP_GS', stdval: 0.33, unit: 'HR' }, ZAP_LH: { acttyp: 'ZAP_LH', stdval: 0.33, unit: 'HR' }, ZAP_OT: { acttyp: 'ZAP_OT', stdval: 0.33, unit: 'HR' }, kwh: 72.67, no_mc_mmbtu: 1.85, noempl: 14.5 } ]; console.log(transform(data));

You can check if val is truthy :

 const data = [{id: '6397f6f46b18bc89cb37053c',cost_center: null,plant: null,material: null,},{id: '6397f7166b18bc89cb372ff7',cost_center: 'C118as0008',short_description: 'LINE PasdNG ALL',plant: 'K1as8',material: '300006',material_name: 'DRILLO PBJ 22g MT (12 pcs x 8 ib)',base_quantity: 218.995,ZAP_DP: {acttyp: 'ZAP_DP',stdval: 0.224,unit: 'HR',},ZAP_EL: {acttyp: 'ZAP_EL',stdval: 0.224,unit: 'HR',},ZAP_LH: {acttyp: 'ZAP_LH',stdval: 0.224,unit: 'HR',},ZAP_OT: {acttyp: 'ZAP_OT',stdval: 0.224,unit: 'HR',},kwh: 35.46,no_mc_mmbtu: 5,noempl: 50,},{id: '6397f7166b18bc89cb373003',cost_center: 'C11asd9',short_description: 'LINE WAasdAT FOX',plant: 'K1aas8',material: '300007',material_name: 'asBAasd0g GT (60 pcs)',base_quantity: 28.816,ZAP_DP: {acttyp: 'ZAP_DP',stdval: 0.33,unit: 'HR',},ZAP_EL: {acttyp: 'ZAP_EL',stdval: 0.33,unit: 'HR',},ZAP_GS: {acttyp: 'ZAP_GS',stdval: 0.33,unit: 'HR',},ZAP_LH: {acttyp: 'ZAP_LH',stdval: 0.33,unit: 'HR',},ZAP_OT: {acttyp: 'ZAP_OT',stdval: 0.33,unit: 'HR',},kwh: 72.67,no_mc_mmbtu: 1.85,noempl: 14.5,},] const transform = data => data.map(el => Object.fromEntries( Object.entries(el).flatMap(([k, v]) => v?.constructor === Object? Object.entries(v).map(([k, v]) => [k + '_' + k, v?? '']): [[k, v?? '']] ) ) ) console.log(transform(data))

You can simply achieve this by assigning an empty string for null and undefined by using nullish coalescing (??) operator.

data.map(el => {
    Object.keys(el).forEach(key => {
    el[key] = el[key] ?? ''
  })
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM