javascriptjson-query

json-query to iterate through an array


I have the below JavaScript file. I want to iterate through the "data" object and print the "ami" values. However, the query is not working. 'result.value' is null. I am not sure what I have done wrong.

What I have so far:

var jsonQuery = require('json-query');

var data = {
    "version": 3,
    "terraform_version": "0.12.31",
    "serial": 1,    
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {
                "aws_instance_tfer--i-0022xxxxxxxxeaf_Oracle-Dev_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-0022xxx"
                },
                "aws_instance_tfer--i-0100xxx_SRE-AMPP02_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-01000xxx"
                },
                "aws_instance_tfer--i-0142545fe3066b603_test-windows-agent_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-01425xxxxx3"
                }
            },
            "resources": {
                "aws_instance.tfer--i-0022xxxxxaf_Oracle-Dev-CMS": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "i-00221xxxxx",
                        "attributes": {
                            "ami": "ami-094axxxx",
                            "arn": "arn:aws",
                            "associate_public_ip_address": "false",
                            "availability_zone": "us-east",
                            "vpc_security_group_ids.0": "sg-0284ccc"
                        },
                        "meta": {
                            "schema_version": 1
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                },
                "aws_instance.tfer--i-0100xxxx_SRE-AMVAPP02": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "i-010001xxxxx",
                        "attributes": {
                            "ami": "ami-0443c",
                            "arn": "arn:aws4",
                            "associate_public_ip_address": "false",
                            "availability_zone": "us-east"    
                        },
                        "meta": {
                            "schema_version": 1
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        }
    ]
}


var result = jsonQuery('modules[0].resources[*type=aws_instance].primary.attributes.ami', {data: data});


console.log(result.value);

I want to iterate through the 'resources' array in the 'data' object and get the below result:

[ "ami-094axxxx", "ami-0443c" ]


Solution

  • You can do it with plain JavaScript:

    var data = {
    "version": 3,
    "terraform_version": "0.12.31",
    "serial": 1,    
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {
                "aws_instance_tfer--i-0022xxxxxxxxeaf_Oracle-Dev_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-0022xxx"
                },
                "aws_instance_tfer--i-0100xxx_SRE-AMPP02_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-01000xxx"
                },
                "aws_instance_tfer--i-0142545fe3066b603_test-windows-agent_id": {
                    "sensitive": false,
                    "type": "string",
                    "value": "i-01425xxxxx3"
                }
            },
            "resources": {
                "aws_instance.tfer--i-0022xxxxxaf_Oracle-Dev-CMS": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "i-00221xxxxx",
                        "attributes": {
                            "ami": "ami-094axxxx",
                            "arn": "arn:aws",
                            "associate_public_ip_address": "false",
                            "availability_zone": "us-east",
                            "vpc_security_group_ids.0": "sg-0284ccc"
                        },
                        "meta": {
                            "schema_version": 1
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                },
                "aws_instance.tfer--i-0100xxxx_SRE-AMVAPP02": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "i-010001xxxxx",
                        "attributes": {
                            "ami": "ami-0443c",
                            "arn": "arn:aws4",
                            "associate_public_ip_address": "false",
                            "availability_zone": "us-east"    
                        },
                        "meta": {
                            "schema_version": 1
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        }
    ]
    }
    
    const res=
    Object.values(data.modules[0].resources)
      .filter(e=>e.type=="aws_instance")
      .map(e=>e.primary.attributes.ami);
    
    console.log(res);

    The values of the .resources object need to be extracted with Object.values() in order to get an array over which we can then .filter() and .map() the appropriate properties.