Search code examples
javascriptlodash

Why lodash converts my array into object?


I am new to lodash, and created a function that removes the key from the object where a value is null or blank. But when i am passing my object which contains some part as array it removes array and converts it into an object.

Below is my code which i tried:

     _.mixin({ 'removeFalsies': this.removeFalsies });
        _.mixin({
                removeEmptyObjects: this.removeEmptyObjects
          });

         removeFalsies (obj) {
    return _.transform(obj, function (o, v, k) {

      if (v && typeof v === 'object') {

        if (v !== '') {
          o[k] = _.removeFalsies(v);
        }

      } else if (v === false) {
        o[k] = v;
      } else if (v) {
        o[k] = v;
      }
    });
  }
  removeEmptyObjects (obj) {
    return _(obj)
      .pickBy(_.isObject)
      .mapValues(_.removeEmptyObjects)
      .omitBy(_.isEmpty)
      .assign(_.omitBy(obj, _.isObject))
      .value();
  }

Below is the JSON which i am providing to omit blank and null value, so it should remove all the properties from "smallMap" object as series, align are blank object and should remove height as well.

On the other hand, it should remove "mid" from heatrules as well as series1 from children array.

var finalProp = {
  "smallMap": {
    "series": {},
    "align": {},
    "height": ""
  },
  "series": [
    {
      "heatRules": [
        {
          "min": "#555",
          "mid": null
        }
      ],
      "mapPolygons": {
        "tooltipText": "{name}",
        "togglable": true
      },
      "id": "value"
    }
  ],
  "children": [
    {
      "type": "HeatLegend",
      "width": "100%",
      "series1": null
    }
  ]
}
_.removeEmptyObjects(_.removeFalsies(finalProp));

It is removing everything as expected but only 1 issue it is converting array to object.

It is providing below incorrect output instead of series: {0 : {}} it should provide series: [{}] and instead of children: {0 :{}} it should provide [{}].

{
      "series": {
        "0": {
          "heatRules": {
            "0": {
              "min": "#555"
            }
      },
      "mapPolygons": {
        "tooltipText": "{name}",
        "togglable": true
      },
      "id": "value"
    }
  },
  "children": {
    "0": {
      "type": "HeatLegend",
      "width": "100%"
    }
  }
}

i am not able to find where is the issue any help is appreciated.


Solution

  • main two problems one which was mention by @Akrion for that you can do something as below:

    removeFalsies (obj) {
    
    return _.transform(obj, function (o, v, k, l) {
    
        // here you have to check for array also as typeof will return object for array also
      if (v && _.isObject(v) && !_.isArray(v)) {
    
        if (v !== '' && !_.omitBy(v, _.isObject)) {
          o[k] = removeFalsies(v);
        }
    
      } else if(_.isArray(v)) {
      if(!o.hasOwnProperty(k)) o[k] = [];
    
      //And if it is array loop through it
    
      _.forEach(v, function(v1, k1) {
         o[k].push(removeFalsies(v1));
      });
    
      } else if (v === false) {
        o[k] = v;
      } else if (v) {
        o[k] = v;
      }
    });
    }
    

    while calling function just try to remove mapValues as it create object and convert array in objects because of that your key 0 is getting converted to key

    removeEmptyObjects =function (obj) {
          return _(obj).pickBy(_.isObject).omitBy(_.isEmpty).assign(_.omitBy(obj, _.isObject)).value();
    }
    

    Hope this will help you, not tested properly yes just short description.