0

I have an nested json object in which I need to remove empty values and create new json which should contain only data objects. json file:

myData = [{
    "id": 1,
    "values": [{
        "value": ""
    }]
}, {
    "id": 2,
    "values": [{
        "value": 213
    }]

}, {
    "id": 3,
    "values": [{
        "value": ""
    }, {
        "value": ""
    }, {
        "value": "abc"
    }]

},{
    "id": 4,
    "values": [{
        "value": ""
    }]
},{
    "id": 33,
    "values": [{
        "value": "d"
    }]
}];

Output should be:

myNewData = [{
    "id": 2,
    "values": [{
        "value": 213
    }]

}, {
    "id": 3,
    "values": [{
        "value": "abc"
    }]

},{
    "id": 33,
    "values": [{
        "value": "d"
    }]
}];

So far I have created this:

    angular.module('myapp',[])
    .controller('test',function($scope){
    $scope.myData = [{
        "id": 1,
        "values": [{
            "value": ""
        }]
    }, {
        "id": 2,
        "values": [{
            "value": 213
        }]

    }, {
        "id": 3,
        "values": [{
            "value": ""
        }, {
            "value": ""
        }, {
            "value": "abc"
        }]

    },{
        "id": 4,
        "values": [{
            "value": ""
        }]
    },{
        "id": 33,
        "values": [{
            "value": "d"
        }]
    }];

})
.filter('filterData',function(){
    return function(data) {
        var dataToBePushed = [];
        data.forEach(function(resultData){
            if(resultData.values && resultData.values != "")
                dataToBePushed.push(resultData);
        });
        return dataToBePushed;
    }
});

Html:

<div ng-app="myapp">
    <div ng-controller="test">
        <div ng-repeat="data in myData | filterData">
            Id:{{ data.id }}
            </br>
            Values: {{ data.values }}
        </div>
    </div>
</div>

I am not able to access and remove value inside values object. Right now i am simply showing the data using ng-repeat but i need to create a new json file for that.

0

6 Answers 6

2

You work with the array in your AngularJS Controller doing Array.prototype.map() and Array.prototype.filter(). Map all objects doing a filter to exclude the items with empty values item.values.value, and than a filter to get the array elements that have values with value:

var myData = [{"id": 1,"values": [{	"value": ""}]}, {"id": 2,"values": [{"value": 213}]}, {"id": 3,"values": [{"value": ""}, {"value": ""}, {"value": "abc"}]}, {"id": 4,"values": [{"value": ""}]}, {"id": 33,"values": [{"value": "d"}]}],
    myDataFiltered = myData
      .map(function (item) {
        item.values = item.values.filter(function (itemValue) {
          return itemValue.value;
        });
        return item;
      })
      .filter(function (item) {
        return item.values.length;
      });

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

ES6:

myDataFiltered = myData
    .map(item => {
        item.values = item.values.filter(itemValue => itemValue.value);
        return item;
    })
    .filter(item => item.values.length);
Sign up to request clarification or add additional context in comments.

1 Comment

Your first filter on myData should be a map, as its not filtering. This would also mutate the original object.
0

Here you go with a multiple for-loop.

myData = [{
    "id": 1,
    "values": [{
        "value": ""
    }]
}, {
    "id": 2,
    "values": [{
        "value": 213
    }]

}, {
    "id": 3,
    "values": [{
        "value": ""
    }, {
        "value": ""
    }, {
        "value": "abc"
    }]

},{
    "id": 4,
    "values": [{
        "value": ""
    }]
},{
    "id": 33,
    "values": [{
        "value": "d"
    }]
}];

function clone(obj){ return JSON.parse(JSON.stringify(obj));}
var result = [];
for(var i = 0; i < myData.length; i++){
	var current = clone(myData[i]);
  for(var j = 0; j < current.values.length; j++){
    if(current.values[j].value == null || current.values[j].value == ""){
      current.values.splice(j, 1);
      j--;
    }
  }
  if(current.values.length > 0) result.push(current);
}
console.log(myData);
console.log(result);

3 Comments

When i run the code snippet it prints the desired result ?
I am not OP but look at your result for id=3
You know that i console.log both arrays ? The myData and the result ?
0

If you want to delete them completely, you can iterate over the array like this;

angular.forEach($scope.myData, function(data){
    for(var i=0; i < data.values.length; i++){
         if(data.values[i] !== ""){
              break;
         }
         delete data;
    }
});

The if statement checks all values in the array, and breaks if it's not equal to "", otherwise if all values are = "" it deletes the object.

Hope it helps!

1 Comment

This doesn't go deeper than one level though.
0

Here's a recursive function to do the job.

This will only work if myData is an array and the value inside it or its children is a collection of object.

var myData = [{"id": 1, "values": [{"value": ""}] }, {"id": 2, "values": [{"value": 213 }] }, {"id": 3, "values": [{"value": ""}, {"value": ""}, {"value": "abc"}] },{"id": 4, "values": [{"value": ""}] },{"id": 6, "values": ""},{"id": 33, "values": [{"value": "d"}] }];

function removeEmptyValues (arr) {
    var res = false;

    /* Iterate the array */
    for (var i = 0; i < arr.length; i++) {
        /* Get the object reference in the array */
        var obj = arr[i];

        /* Iterate the object based on its key */
        for (var key in obj) {

            /* Ensure the object has the key or in the prototype chain */
            if (obj.hasOwnProperty(key)) {

                /* So, the object has the key. And we want to check if the object property has a value or not */
                if (!obj[key]) {

                    /*
                        If it has no value (null, undefined, or empty string) in the property, then remove the whole object,
                        And reduce `i` by 1, to do the re-checking
                    */
                    arr.splice(i--, 1);

                    /* Amd set whether the removal occurance by setting it to res (result), which we will use for the next recursive function */
                    res = true;

                    /* And get out from the loop */
                    break;
                }

                /* So, the object has a value. Let's check whether it's an array or not */
                if (Array.isArray(obj[key])) {

                    /* Kay.. it's an array. Let's see if it has anything in it */
                    if (!obj[key].length) {

                        /* There's nothing in it !! Remove the whole object again */
                        arr.splice(i--, 1);

                        /* Amd set whether the removal occurance by setting it to res (result), which we will use for the next recursive function */
                        res = true;

                        /* Yes.. gets out of the loop */
                        break;
                    }

                    /*
                        Now this is where `res` is being used.
                        If there's something removed, we want to re-do the checking of the whole object
                    */
                    if ( removeEmptyValues(obj[key]) ) {

                        /* Something has been removed, re-do the checking */
                        i--;
                    }
                }
            }
        }
    }

    return res;
}

removeEmptyValues (myData);

Comments

0

Try this:

var myData = [{"id": 1,"values": [{ "value": ""}]}, {"id": 2,"values": [{"value": 213}]}, {"id": 3,"values": [{"value": ""}, {"value": ""}, {"value": "abc"}]}, {"id": 4,"values": [{"value": ""}]}, {"id": 33,"values": [{"value": "d"}]}]

let result=[],p=[];
myData.filter(el => {    
     p=[]; 
     el.values.filter(k => {k.value != '' ? p.push({value : k.value}) : null}); 
     if(p.length) result.push({id : el.id, values : p})
})
    
console.log('result', result);

Comments

0

You are going to right way but need some more operation like this :

 angular.module('myapp',[])
    .controller('test',function($scope){
    $scope.myData = [{
        "id": 1,
        "values": [{
            "value": ""
        }]
    }, {
        "id": 2,
        "values": [{
            "value": 213
        }]

    }, {
        "id": 3,
        "values": [{
            "value": ""
        }, {
            "value": ""
        }, {
            "value": "abc"
        }]

    },{
        "id": 4,
        "values": [{
            "value": ""
        }]
    },{
        "id": 33,
        "values": [{
            "value": "d"
        }]
    }];

})
.filter('filterData',function($filter){
    return function(data) {
        var dataToBePushed = [];
        data.forEach(function(resultData){
          var newValues=resultData;
          var hasData=$filter('filter')(resultData.values,{value:'!'},true);
          if(resultData.values && resultData.values.length>0 && hasData.length>0){
              newValues.values=hasData;
                dataToBePushed.push(newValues);
              }
        });
      debugger;
        return dataToBePushed;
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
    <div ng-controller="test">
        <div ng-repeat="data in myData | filterData:''">
            Id:{{ data.id }}
            </br>
            Values: {{ data.values }}
        </div>
    </div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.