1

I have a JSON object which I get by default :-

$scope.ContentObj= {
      "attribute-set": [
        {
          "attribute": [
            {
              "_name": "text-align",
              "__prefix": "xsl",
              "__text": "end"
            },
            {
              "_name": "end-indent",
              "__prefix": "xsl",
              "__text": "10pt"
            }
          ],
          "_name": "odd__header",
          "__prefix": "xsl"
        },
        {
          "attribute": {
            "_name": "font-weight",
            "__prefix": "xsl",
            "__text": "bold"
          },
          "_name": "pagenum",
          "__prefix": "xsl"
        }
      ],
      "_version": "2.0",
      "__prefix": "xsl"
    }

NOTE:- I am doing the operation on attribute of second attribute-set name: pagenum

Now , I am making the attribute-set[1]-> attribute an array since it is an object. I am making attribute an array because I need to push more objects in it.

if(typeof $scope.ContentObj.stylesheet["attribute-set"][1].attribute === "object"){ //Check if object
                const content = $scope.ContentObj.stylesheet["attribute-set"][1].attribute; //Get the content
                $scope.ContentObj.stylesheet["attribute-set"][1].attribute = [content]; //Put the content in an array
            }

Now it is successfully creating an array :-

$scope.ContentObj= {
      "attribute-set": [
        {
          "attribute": [
            {
              "_name": "text-align",
              "__prefix": "xsl",
              "__text": "end"
            },
            {
              "_name": "end-indent",
              "__prefix": "xsl",
              "__text": "10pt"
            }
          ],
          "_name": "odd__header",
          "__prefix": "xsl"
        },
        {
          "attribute":[
          {
            "_name": "font-weight",
            "__prefix": "xsl",
            "__text": "bold"
          }
          ],
          "_name": "pagenum",
          "__prefix": "xsl"
        }
      ],
      "_version": "2.0",
      "__prefix": "xsl"
    }

After this I am trying to push by the objects by checking _name which is already present there or not . I am able to push this code successfully in the array by following code :-

//check color  
    var checkContentPageColor = obj => obj._name === 'color';
//for checking font name
    var checkContentPageFont = obj => obj._name === 'font-family';

//check color in the attr json
var checkContentPageColor_available = $scope.ContentObj.stylesheet["attribute-set"][1].attribute.some(checkContentPageColor);
// check font family
var checkContentPageFont_available = $scope.ContentObj.stylesheet["attribute-set"][1].attribute.some(checkContentPageFont);

                if( checkContentPageColor_available === false && checkContentPageFont_available  === false ){
                    console.log('not available' );
                    $scope.ContentObj.stylesheet["attribute-set"][1].attribute.push({
                                "_name": "color",
                                "__prefix": "xsl",
                                "__text": "black"
                              },{
                                "_name": "font-family",
                                "__prefix": "xsl",
                                "__text": "sans"
                              }
                              );
                    console.log("pushed successfully");     
                    console.log($scope.ContentObj);             
                }

So now , I am getting result like this { attribute: [{..},{..},{..}],something } which is correct. :-

$scope.ContentObj= {
      "attribute-set": [
        {
          "attribute": [
            {
              "_name": "text-align",
              "__prefix": "xsl",
              "__text": "end"
            },
            {
              "_name": "end-indent",
              "__prefix": "xsl",
              "__text": "10pt"
            }
          ],
          "_name": "odd__header",
          "__prefix": "xsl"
        },
        {
          "attribute":[
          {
        "_name": "font-weight",
        "__prefix": "xsl",
        "__text": "100"
      },
      {
        "_name": "color",
        "__prefix": "xsl",
        "__text": "black"
      },
      {
        "_name": "font-family",
        "__prefix": "xsl",
        "__text": "sans"
      }
          ],
          "_name": "pagenum",
          "__prefix": "xsl"
        }
      ],
      "_version": "2.0",
      "__prefix": "xsl"
    }

After this when I am reloading the app , the code is getting push again making double array. The JSON now looks like this { attribute: [[{..},{..},{..}],{..},{..}],something } :-

    {
          "attribute-set": [
            {
              "attribute": [
                {
                  "_name": "text-align",
                  "__prefix": "xsl",
                  "__text": "end"
                },
                {
                  "_name": "end-indent",
                  "__prefix": "xsl",
                  "__text": "10pt"
                }
              ],
              "_name": "odd__header",
              "__prefix": "xsl"
            },
            {
              "attribute":[[
              {
            "_name": "font-weight",
            "__prefix": "xsl",
            "__text": "100"
          },
          {
            "_name": "color",
            "__prefix": "xsl",
            "__text": "black"
          },
          {
            "_name": "font-family",
            "__prefix": "xsl",
            "__text": "sans"
          }],
          {
            "_name": "color",
            "__prefix": "xsl",
            "__text": "black"
          },
          {
            "_name": "font-family",
            "__prefix": "xsl",
            "__text": "sans"
          }
              ],
              "_name": "pagenum",
              "__prefix": "xsl"
            }
          ],
          "_version": "2.0",
          "__prefix": "xsl"
}

Where am I going wrong ? Suggest some changes according to my code which I should make. I am stuck here since long time.

2
  • Maybe add the 'return' keyword in the checkContentPageColor and checkContentPageFont function definitions? Commented Dec 17, 2018 at 11:48
  • Nope , didn't helped. :( can you explain by editing the code ? Commented Dec 17, 2018 at 12:22

3 Answers 3

1

The problem is the way you are trying to distinguish between an "Object" and an "Array" - Arrays are objects

if(typeof $scope.ContentObj.stylesheet["attribute-set"][1].attribute === "object"){ ... } //Check if object

This is always true - consider this:

const o = {"A": 1, "B": 2}
const l = [o]
const n = [1, 2]

typeof(o) //"object"
typeof(l) //"object"
typeof(n) //"object"

What you probably want to use instead is instanceof

o instanceof Array //false
l instanceof Array //true
n instance of Array //true
Sign up to request clarification or add additional context in comments.

2 Comments

So you are suggesting to change this in if(instanceof $scope.ContentObj.stylesheet["attribute-set"][1].attribute === "object"){ ... } //Check if object
if(!($scope.ContentObj.stylesheet["attribute-set"][1].attribute instanceof Array)) { ... }
1

If I am not wrong, at first you are checking if object is an object and then pushing what it contains to an array. After reloading, you are checking if the array is an object what is true so you are again putting content of your array to another array and pushing duplicate of your content. That is why you obtained something like this:

{ attribute: [[{..},{..},{..}],{..},{..}],something }

and not like this:

{ attribute: [{..},{..},{..},{..},{..}],something }.

1 Comment

1. Yes first I am checking if object is an object. If object then make it array. 2. Not after reload , the entire operation is happening on same load of controller. In second I am checking if in that array after array has been created , if there is objects by those names obj._name === 'color'; & obj._name === 'font-family';. Yes you are right after reload ,I am again putting this content but not getting how can I resolve it.
0

You should check if the value of the key "_name" already exists. Here's a small utility, which checks if a particular attribute _name exists and automatically push it to the array if the attribute _name is not found.

Sandbox: https://codesandbox.io/s/o1vpkxv5w5

function addAtts(arr, att) {
    var found = arr.some(function (at) {
      return at._name === att._name;
    });
    if (!found) {
        arr.push(att);
    }
}

addAtts(object["attribute-set"][1].attribute, {
    "_name": "color",
    "__prefix": "xsl",
    "__text": "black"
});

addAtts(object["attribute-set"][1].attribute, {
    "_name": "font-family",
    "__prefix": "xsl",
    "__text": "sans"
});

console.log(object["attribute-set"][1]);

Result:

{ attribute:
   [ { _name: 'font-weight', __prefix: 'xsl', __text: 'bold' },
     { _name: 'color', __prefix: 'xsl', __text: 'black' },
     { _name: 'font-family', __prefix: 'xsl', __text: 'sans' } ],
  _name: 'pagenum',
  __prefix: 'xsl' }

Let's try to run it again pushing the same attributes but let's add a new one.

addAtts(object["attribute-set"][1].attribute, {
    "_name": "color",
    "__prefix": "xsl",
    "__text": "black"
});

addAtts(object["attribute-set"][1].attribute, {
    "_name": "font-family",
    "__prefix": "xsl",
    "__text": "sans"
});

addAtts(object["attribute-set"][1].attribute, {
    "_name": "font-family",
    "__prefix": "xsl",
    "__text": "sans"
});

console.log(object["attribute-set"][1]);

Result:

{ attribute:
   [ { _name: 'font-weight', __prefix: 'xsl', __text: 'bold' },
     { _name: 'color', __prefix: 'xsl', __text: 'black' },
     { _name: 'font-family', __prefix: 'xsl', __text: 'sans' },
     { _name: 'text-decoration',
       __prefix: 'xsl',
       __text: 'underline' } ],
  _name: 'pagenum',
  __prefix: 'xsl' }

Please note that the "$scope.ContentObj.stylesheet" object is the variable "object" in the sandbox.

1 Comment

No , again an array is getting created. I have changed the value of color and font-family and after updating, array is getting added same like my problem. I tried your code if you change the value then it is not getting updated. { attribute: [ [ { _name: 'font-weight', __prefix: 'xsl', __text: 'bold' }, { _name: 'color', __prefix: 'xsl', __text: 'red' }, { _name: 'font-family', __prefix: 'xsl', __text: 'tahoma' }],{ _name: 'color', __prefix: 'xsl', __text: 'black' }, { _name: 'font-family', __prefix: 'xsl', __text: 'sans' }],name: 'pagenum', __prefix: 'xsl' }

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.