2

I am working with the TomTom places api as part of a project. I am new to Javascript and I'm finding it difficult to extract the information I need from the API. I am trying to get all names, phone numbers, addresses and urls from the results array. This is what I'm working with -

"summary": {
  "query": "restaurant",
  "queryType": "NON_NEAR",
  "queryTime": 126,
  "numResults": 10,
  "offset": 0,
  "totalResults": 102131,
  "fuzzyLevel": 1,
  "geoBias": {
    "lat": 50.266,
    "lon": 5.0527
  }
},
"results": [{
  "type": "POI",
  "id": "GB/POI/p0/1035734",
  "score": 2.1523399353027344,
  "dist": 277294.490777698,
  "info": "search:ta:826009007710588-GB",
  "poi": {
    "name": "Bay Restaurant",
    "phone": "+(44)-(1304)-852229",
    "categorySet": [{
      "id": 7315008
    }],
    "url": "thewhitecliffs.com",
    "categories": [
      "british",
      "restaurant"
    ],
    "classifications": [{
      "code": "RESTAURANT",
      "names": [{
          "nameLocale": "en-US",
          "name": "restaurant"
        },
        {
          "nameLocale": "en-US",
          "name": "british"
        }
      ]
    }]
  },
  "address": {},
  "position": {
    "lat": 51.15375,
    "lon": 1.37204
  },
  "viewport": {
    "topLeftPoint": {
      "lat": 51.15465,
      "lon": 1.37061
    },
    "btmRightPoint": {
      "lat": 51.15285,
      "lon": 1.37347
    }
  },
  "entryPoints": [{
    "type": "main",
    "position": {
      "lat": 51.15375,
      "lon": 1.37204
    }
  }]
}

So far, I've managed to get the name for result number one by doing -

function callbackFn(result) {
  console.log(result[0].poi.name)
}

And I've managed to do the same for the phone number by doing -

function callbackFn(result) {
  console.log(result[0].poi.phone)
}

However, I do not know how to grab that data for all of the results given. The number of results given varies depending on the search criteria, so I'd like to preferably be able to get the names, phone numbers, addresses and urls of all the results whether there are 8 or 100.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
pypyi
  • 23
  • 4

3 Answers3

3

You can use the Array.prototype.map() method with object destructuring to select the specific properties you want:

function callbackFn(results) {
  const data = results.map(result => {
    const { poi, address } = result;
    const { name, phone, url } = poi;
    return { name, phone, address, url };
  });

  console.log(data);
}

const results = [{
  "type": "POI",
  "id": "GB/POI/p0/1035734",
  "score": 2.1523399353027344,
  "dist": 277294.490777698,
  "info": "search:ta:826009007710588-GB",
  "poi": {
    "name": "Bay Restaurant",
    "phone": "+(44)-(1304)-852229",
    "categorySet": [{
      "id": 7315008
    }],
    "url": "thewhitecliffs.com",
    "categories": [
      "british",
      "restaurant"
    ],
    "classifications": [{
      "code": "RESTAURANT",
      "names": [{
          "nameLocale": "en-US",
          "name": "restaurant"
        },
        {
          "nameLocale": "en-US",
          "name": "british"
        }
      ]
    }]
  },
  "address": {},
  "position": {
    "lat": 51.15375,
    "lon": 1.37204
  },
  "viewport": {
    "topLeftPoint": {
      "lat": 51.15465,
      "lon": 1.37061
    },
    "btmRightPoint": {
      "lat": 51.15285,
      "lon": 1.37347
    }
  },
  "entryPoints": [{
    "type": "main",
    "position": {
      "lat": 51.15375,
      "lon": 1.37204
    }
  }]
}]

callbackFn(results);
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
2

You're effectively about halfway there, you just need to replace the specific index with one that increases. You can just loop over the array (using a for, for...of or while loop): if you're unsure of how to do this, there are a vast number of guides to the basics, so definitely have a Google around: here's the MDN introductory article in iteration, which is pretty good: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code

The array method "map" would be the more sensible, declarative way to do what you want to do, but if you're stuck at this point then you may find map is slightly more confusing, as it depends on understanding how higher-order functions work.

DanCouper
  • 850
  • 6
  • 15
1

Use Array.map() to flatten the object. I simplified the object (Works the same) and used ternary operators inside the returned object literal in case any of the properties didn't exist.

let obj = {

  "summary": {
    "query": "restaurant"
  },
  "results": [{
      "poi": {
        "name": "Bay Restaurant",
        "phone": "+(44)-(1304)-852229",
        "url": "thewhitecliffs.com",
      },
      "address": {
        "stAddr": "1234 main st",
        "city": "Your City",
        "state": "Your State"
      },
    },
    {
      "poi": {
        "name": "Other Bay Restaurant",
        "phone": "Other +(44)-(1304)-852229",
        "url": "Other thewhitecliffs.com",
      },
      "address": {
        "stAddr": "Other 1234 main st",
        "city": "Other Your City",
        "state": "Other Your State"
      },
    }
  ]
}

let result = obj.results.map(el => {
    return {
        name: el.poi && el.poi.name ? el.poi.name : "",
        phone: el.poi && el.poi.phone ? el.poi.phone : "",
        url: el.poi && el.poi.url ? el.poi.url : "",
        stAddr: el.address && el.address.stAddr ? el.address.stAddr : "",
        city: el.address && el.address.city ? el.address.city : "",
        state: el.address && el.address.state ?  el.address.state : ""
    }
})

console.log(result)
symlink
  • 11,984
  • 7
  • 29
  • 50
  • 1
    In the future you'll be able to do `{ name: el?.pi?.name ?? "", phone: el?.poi?.phone ?? "", ... }` etc. using [optional chaining](https://github.com/tc39/proposal-optional-chaining) and [nullish coalescing](https://github.com/tc39/proposal-nullish-coalescing). – Patrick Roberts Jan 03 '20 at 19:34