6

I'm building an API endpoint which will return details and a single photo of a Google place using express.js and Node.js client library for Google Maps API Web Services. The endpoint below returns details of a place and I'm having trouble retrieving the URL of a photo. Below is the code in question.

There are two requests to the google maps client:

  1. Get place details based on req.params.id and the details contain a photos array
  2. Get photo using the photo_reference from above

    var googleMapsClient = require('@google/maps').createClient({
      key: 'mykeyhere',
      Promise: Promise
    });
    
    exports.getGglPlace = function(req, res) {
    
    googleMapsClient.place({
         placeid: req.params.id
    }).asPromise()
    .then((response) => {
      var venue = response.json.result
    
      if (venue.photos[0]) {
        googleMapsClient.placesPhoto({
          photoreference: venue.photos[0].photo_reference,
          maxwidth: 200
        }).asPromise()
        .then((photo) => {
    
          console.log("Photo:", photo); // this returns a massive chunk of data which I think contains the actual image object also
          venue.photoURL = photo.url; // this doesn't work
    
          res.send(venue);
        })
        .catch((err)=>{
          console.log("Error Getting Photo!", err);
          res.send(venue);
        })
      } else {
        res.send(venue);
      }
    })
    .catch((err) => {
      res.send(404);
    })
    }
    

Any idea how to obtain the URL from the response which is called photo in the code above?

If I try going to the API directly through the browser or Postman, the URL gets redirected to the actual source URL of the image, which is what I want to add to my venue object.

API request example: https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CmRaAAAA8NPP1nJJ7RCzcQDGUrpBHJXlzlQkN74dcyQJ2ytVpeYIu47sR-8dfCjke1J5exP-HpkayaXOc26ShsVKkXOaJZBOdpmExUfCzUTIBN3x0uPfR5Nt3PnN-a3GoRVZ7YxKEhBvqXF356Tn9mBJ7lA_JQ_7GhQMKvZkOk-Rs9knsansx5yuhfIvsQ&sensor=false&key=mykeyhere

Redirects to (this is what I want photo.url to return): https://lh3.googleusercontent.com/p/AF1QipPVD12HA5FBnjmiqVLphYgjfPtIPydn4Ie-xGKr=s1600-w200

Any help is appreciated.

P.S. My first post here - sorry if I'm not clear enough with my question.

boomer4you
  • 151
  • 1
  • 7
  • I found a similar question [here](https://stackoverflow.com/questions/39508823/how-process-response-object-from-google-places-api-placesphoto), but it has no answer – boomer4you Nov 25 '17 at 18:36

5 Answers5

9

Here is how I solved it. It doesn't seem perfect, but it does the job.

The response contains a req section which has keys in there that I was able to use to build the URL. Specifically, the response.req.socket._host key and the response.req.path key.

Here is what it looks like in my code (where photo is the response from google API)

venue.photoURL = "https://" + photo.req.socket._host + photo.req.path;

photo.req.socket._host gives me lh3.googleusercontent.com

photo.req.path gives me /p/AF1QipPVD12HA5FBnjmiqVLphYgjfPtIPydn4Ie-xGKr=s1600-w200

Results of the constructed URL to the photo is: https://lh3.googleusercontent.com/p/AF1QipPVD12HA5FBnjmiqVLphYgjfPtIPydn4Ie-xGKr=s1600-w200

boomer4you
  • 151
  • 1
  • 7
  • 3
    Yeah I think this works, but it's incredibly tedious. I wonder, anyone knows why this library has such a problematic implementation? This doesn't seem friendly at all to the 3rd party developer consuming the Google Places Photo API – nickang Apr 02 '18 at 08:10
  • you can get the url without constructing it, like this: `response.req._redirectable._options.href`. If this does not work for you try `response.request._redirectable._options.href`, because some libraries name the response object **`req`**, others **`request`** (Axios uses `request`). See my answer below. – dcts Mar 12 '20 at 19:36
1

you can do this

with axios

axios.get(url).then(res => {
  console.log(res.request._redirectable._options.href));
});

with node-fetch

fetch(url).then(res => {
  console.log(res.url);
});

IMPORTANT: make sure you have the package you use installed and required and make sure the url you use works in your browser.

dcts
  • 1,479
  • 15
  • 34
0

The response of a successful Place Photo request will be an image, not an object literal.

https://developers.google.com/places/web-service/photos

The way the browse knows how to redirect to the photo is via a header. If you check out the response you will see it returns a 302 (redirect) and follows the response header location. You should be able to grab that header in express via:

res.get('location');
// => "image url"
Seth
  • 96
  • 4
  • unfortunately that didn't do it. On my end response returns `status: 200` and `.get` is not recognized. Moreover, there is nothing in the response that I found that's called "location". – boomer4you Dec 05 '17 at 15:48
  • Here is an example of the header that comes in the response (called photo in the code above): https://codepad.co/snippet/eoXu0bzS#_=_ – boomer4you Dec 05 '17 at 15:52
0

This code below works on my clientside JS project. Thus, I am able to retrieve place data and its photos as useful link and push it into img src on my html. Maybe it could be useful.

   var service = new google.maps.places.PlacesService(map);
   service.nearbySearch({
        location: latlonNearby,
        radius: 500,
        type: NearbyTypes,
        keyword: ['kafe', 'caffe']
   }, callback);
   function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
        for (let i = 0; i < results.length; i++) {
           // I retrieved first added photo "photos[0]" //
           var placePhotoUrl = results[i].photos[0].getUrl({maxWidth:640}); 
           console.log(placePhotoUrl);
           // Then Do Whatever You Want with this placePhotoUrl //
           }
        }
    }
0

If you use postman, you must turn of settings->automatically follow redirects, then you'll se something like this

   <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://lh3.googleusercontent.com/p/blahblah">here</A>.
</BODY></HTML>

Follow url to find image.

Dgloria
  • 161
  • 1
  • 12