2

an API is returning a JSON that looks like this:

{
   "html_attributions" : [],
   "result" : {
      "address_components" : [
         {
            "long_name" : "1-3",
            "short_name" : "1-3",
            "types" : [ "street_number" ]
         },
         {
            "long_name" : "Acacia",
            "short_name" : "Acacia",
            "types" : [ "route" ]
         },
         {
            "long_name" : "Alamos 2da Sección",
            "short_name" : "Alamos 2da Secc",
            "types" : [ "sublocality_level_1", "sublocality", "political" ]
         },
         {
            "long_name" : "Santiago de Querétaro",
            "short_name" : "Santiago de Querétaro",
            "types" : [ "locality", "political" ]
         },
         {
            "long_name" : "Querétaro",
            "short_name" : "Qro.",
            "types" : [ "administrative_area_level_1", "political" ]
         },
         {
            "long_name" : "Mexico",
            "short_name" : "MX",
            "types" : [ "country", "political" ]
         },
         {
            "long_name" : "76160",
            "short_name" : "76160",
            "types" : [ "postal_code" ]
         }
      ]
   },
   "status" : "OK"
}

I wold like to access the "sublocality" object and read it's value which in this case is "alamos 2da secc". I know the JSON must first be parsed using JSON.parse but im not sure how to access a specific object. Is a for loop necessary? or is there a way i can match the type field for every object to be "sublocality"

Any assistance is appreciated.

Luis
  • 305
  • 1
  • 14
  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](https://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Felix Kling Jan 07 '19 at 16:00
  • @Louis If my answer below solved your problem, would you please mark it as "accepted" by clicking the grey checkmark √? – RobertAKARobin Jan 08 '19 at 01:52

4 Answers4

2

If there may be multiple addresses that are sublocalities, I would go with this approach:

const response = JSON.parse(apiResponse)
const addressesWithSublocality = response['result']['address_components'].filter(address=>{
    return address['types'].includes('sublocality')
})
console.log(addressesWithSublocality.map(address=>address['short_name']))

The .filter function takes an array and trims it down to just the items that return "true" -- in this case, the addresses whose types includes "sublocality".

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

The .map function returns a new array that is the result of running a provided function on each item in the original array -- in this case, returning the short_name of each address.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

If there will only ever be one address that is a sublocality, I would go with this approach:

const response = JSON.parse(apiResponse)
const addressWithSublocality = response['result']['address_components'].find(address=>{
    return address['types'].includes('sublocality')
})
console.log(address['short_name'])

.find is similar to .filter in that it trims down an array based on which items return "true", but .find returns just one item, whereas .filter always returns an array.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Note: Instead of using bracket notation you could just use dot notation, e.g. instead of response['result']['address_components'] you could write response.result.address_components. I just prefer the former syntax when accessing JSON.

RobertAKARobin
  • 3,933
  • 3
  • 24
  • 46
0

Use Array find() to find the required Object.

var data = `{"html_attributions":[],"result":{"address_components":[{"long_name":"1-3","short_name":"1-3","types":["street_number"]},{"long_name":"Acacia","short_name":"Acacia","types":["route"]},{"long_name":"Alamos 2da Sección","short_name":"Alamos 2da Secc","types":["sublocality_level_1","sublocality","political"]},{"long_name":"Santiago de Querétaro","short_name":"Santiago de Querétaro","types":["locality","political"]},{"long_name":"Querétaro","short_name":"Qro.","types":["administrative_area_level_1","political"]},{"long_name":"Mexico","short_name":"MX","types":["country","political"]},{"long_name":"76160","short_name":"76160","types":["postal_code"]}]},"status":"OK"}`

data = JSON.parse(data)

var res = data['result']['address_components'].find((e) => {return e.types.indexOf('sublocality') !== -1})

console.log(res['short_name'])
Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51
0

Using Array#filter find all the names that match the type passed as a parameter.

There may be more than one possible match.

const data ={"html_attributions":[],"result":{"address_components":[{"long_name":"1-3","short_name":"1-3","types":["street_number"]},{"long_name":"Acacia","short_name":"Acacia","types":["route"]},{"long_name":"Alamos 2da Sección","short_name":"Alamos 2da Secc","types":["sublocality_level_1","sublocality","political"]},{"long_name":"Santiago de Querétaro","short_name":"Santiago de Querétaro","types":["locality","political"]},{"long_name":"Querétaro","short_name":"Qro.","types":["administrative_area_level_1","political"]},{"long_name":"Mexico","short_name":"MX","types":["country","political"]},{"long_name":"76160","short_name":"76160","types":["postal_code"]}]},"status":"OK"};

function findMatches(type){
  return data.result.address_components
  .filter(({types})=>types.includes(type))
  .map(({short_name})=>short_name)
  .join(", ");
}

const res = findMatches("sublocality");

console.log(res);
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
0

You could also use _find from Lodash to find the object

const response = {
   "html_attributions" : [],
   "result" : {
      "address_components" : [
         {
            "long_name" : "1-3",
            "short_name" : "1-3",
            "types" : [ "street_number" ]
         },
         {
            "long_name" : "Acacia",
            "short_name" : "Acacia",
            "types" : [ "route" ]
         },
         {
            "long_name" : "Alamos 2da Sección",
            "short_name" : "Alamos 2da Secc",
            "types" : [ "sublocality_level_1", "sublocality", "political" ]
         },
         {
            "long_name" : "Santiago de Querétaro",
            "short_name" : "Santiago de Querétaro",
            "types" : [ "locality", "political" ]
         },
         {
            "long_name" : "Querétaro",
            "short_name" : "Qro.",
            "types" : [ "administrative_area_level_1", "political" ]
         },
         {
            "long_name" : "Mexico",
            "short_name" : "MX",
            "types" : [ "country", "political" ]
         },
         {
            "long_name" : "76160",
            "short_name" : "76160",
            "types" : [ "postal_code" ]
         }
      ]
   },
   "status" : "OK"
}

const addressWithSub = _.find(response.result.address_components , (e) => {return e.types.includes('sublocality')})

console.log(addressWithSub.long_name)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.js"></script>
Meheret
  • 19
  • 2
  • 4