1

I'm currently playing with the google places api to gain some comfort level with it, but I've come up on an issue that has me a little stumped and I'm hoping someone can course correct me here. I'm making api calls to a local proxy server, and so far everything is working except when I try to pull an image for a specific business.

I've gone so far as to console log each individual part of the get request url to ensure it's correctly concatenated and everything appears correct in that regard (I'm able to paste it straight into the browser and get the expected result). I have a hunch this is a general code issue and not something specific to places api itself, but any insight into this would be greatly appreciated.

Error in terminal from proxy server (doesn't seem terribly useful, but someone else might recognize something here that I'm not):

undefined:1 ���� ^

SyntaxError: Unexpected token � in JSON at position 0

Front end code:

function makeAPICall(url) {
  return fetch(url);
}

makeAPICall(`http://localhost:5000/places/${searchString}`)
      .then(response => {
        return response.json();
      })
      .then(data => {
        responseObject = data.results;
        renderResult(responseObject[10]);

        return responseObject[10];
      })
      .then(responseObject => {
        makeAPICall(`http://localhost:5000/place/image/${responseObject.photos[0].photo_reference}`)
          .then(response => {
            return response.json();
          })
          .then(photoData => {
            console.log(photoData);
          });
      });

Proxy code (minus the working routes not relevant to the issue):

require('dotenv').config({path: '../.env'});

const express = require('express');
const request = require('request');

const GOOGLE_API_KEY = process.env.API_KEY;
const placesImgURL = 'https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=';

const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.get('/place/image/:query', (req, res) => {
  request(
    { url: `${placesImgURL}${req.params.query}&key=${GOOGLE_API_KEY}` },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        console.log(response);
      }

      res.json(JSON.parse(body));
    }
  )
});

const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

UPDATE:

The line in the server code where the error is triggered is:

res.json(JSON.parse(body));

Screenshot of network call from within dev tools: enter image description here

When console logging the line that's throwing an error, I get the following (fair warning, this is the full log and it's extremely long):

ServerResponse {
  _events: { finish: [Function: bound resOnFinish] },
  _eventsCount: 1,
  _maxListeners: undefined,
  output: [],
  outputEncodings: [],
  outputCallbacks: [],
  outputSize: 0,
  writable: true,
  _last: false,
  chunkedEncoding: false,
  shouldKeepAlive: true,
  useChunkedEncodingByDefault: true,
  sendDate: true,
  _removedConnection: false,
  _removedContLen: false,
  _removedTE: false,
  _contentLength: 22631,
  _hasBody: true,
  _trailer: '',
  finished: true,
  _headerSent: true,
  socket:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      TCP {
        reading: true,
        onread: [Function: onStreamRead],
        onconnection: null,
        _consumed: true,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events:
      { end: [Array],
        drain: [Array],
        timeout: [Function: socketOnTimeout],
        data: [Function: bound socketOnData],
        error: [Function: socketOnError],
        close: [Array],
        resume: [Function: onSocketResume],
        pause: [Function: onSocketPause] },
     _eventsCount: 8,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: true,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: false,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 3,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: true,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server:
      Server {
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _connections: 1,
        _handle: [TCP],
        _usingWorkers: false,
        _workers: [],
        _unref: false,
        allowHalfOpen: true,
        pauseOnConnect: false,
        httpAllowHalfOpen: false,
        timeout: 120000,
        keepAliveTimeout: 5000,
        _pendingResponseData: 0,
        maxHeadersCount: null,
        _connectionKey: '6::::5000',
        [Symbol(IncomingMessage)]: [Function],
        [Symbol(ServerResponse)]: [Function],
        [Symbol(asyncId)]: 5 },
     _server:
      Server {
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _connections: 1,
        _handle: [TCP],
        _usingWorkers: false,
        _workers: [],
        _unref: false,
        allowHalfOpen: true,
        pauseOnConnect: false,
        httpAllowHalfOpen: false,
        timeout: 120000,
        keepAliveTimeout: 5000,
        _pendingResponseData: 0,
        maxHeadersCount: null,
        _connectionKey: '6::::5000',
        [Symbol(IncomingMessage)]: [Function],
        [Symbol(ServerResponse)]: [Function],
        [Symbol(asyncId)]: 5 },
     timeout: 120000,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': [Function: bound onParserExecute],
        _headers: [],
        _url: '',
        _consumed: true,
        socket: [Circular],
        incoming: [IncomingMessage],
        outgoing: null,
        maxHeaderPairs: 2000,
        onIncoming: [Function: bound parserOnIncoming] },
     on: [Function: socketOnWrap],
     _paused: false,
     _httpMessage: [Circular],
     [Symbol(asyncId)]: 8,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]:
      Timeout {
        _called: false,
        _idleTimeout: 120000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 6746,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(unrefed)]: true,
        [Symbol(asyncId)]: 9,
        [Symbol(triggerId)]: 8 },
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  connection:
   Socket {
     connecting: false,
     _hadError: false,
     _handle:
      TCP {
        reading: true,
        onread: [Function: onStreamRead],
        onconnection: null,
        _consumed: true,
        [Symbol(owner)]: [Circular] },
     _parent: null,
     _host: null,
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: false,
        endEmitted: false,
        reading: true,
        sync: false,
        needReadable: true,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events:
      { end: [Array],
        drain: [Array],
        timeout: [Function: socketOnTimeout],
        data: [Function: bound socketOnData],
        error: [Function: socketOnError],
        close: [Array],
        resume: [Function: onSocketResume],
        pause: [Function: onSocketPause] },
     _eventsCount: 8,
     _maxListeners: undefined,
     _writableState:
      WritableState {
        objectMode: false,
        highWaterMark: 16384,
        finalCalled: false,
        needDrain: true,
        ending: false,
        ended: false,
        finished: false,
        destroyed: false,
        decodeStrings: false,
        defaultEncoding: 'utf8',
        length: 0,
        writing: false,
        corked: 0,
        sync: false,
        bufferProcessing: false,
        onwrite: [Function: bound onwrite],
        writecb: null,
        writelen: 0,
        bufferedRequest: null,
        lastBufferedRequest: null,
        pendingcb: 3,
        prefinished: false,
        errorEmitted: false,
        emitClose: false,
        bufferedRequestCount: 0,
        corkedRequestsFree: [Object] },
     writable: true,
     allowHalfOpen: true,
     _sockname: null,
     _pendingData: null,
     _pendingEncoding: '',
     server:
      Server {
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _connections: 1,
        _handle: [TCP],
        _usingWorkers: false,
        _workers: [],
        _unref: false,
        allowHalfOpen: true,
        pauseOnConnect: false,
        httpAllowHalfOpen: false,
        timeout: 120000,
        keepAliveTimeout: 5000,
        _pendingResponseData: 0,
        maxHeadersCount: null,
        _connectionKey: '6::::5000',
        [Symbol(IncomingMessage)]: [Function],
        [Symbol(ServerResponse)]: [Function],
        [Symbol(asyncId)]: 5 },
     _server:
      Server {
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _connections: 1,
        _handle: [TCP],
        _usingWorkers: false,
        _workers: [],
        _unref: false,
        allowHalfOpen: true,
        pauseOnConnect: false,
        httpAllowHalfOpen: false,
        timeout: 120000,
        keepAliveTimeout: 5000,
        _pendingResponseData: 0,
        maxHeadersCount: null,
        _connectionKey: '6::::5000',
        [Symbol(IncomingMessage)]: [Function],
        [Symbol(ServerResponse)]: [Function],
        [Symbol(asyncId)]: 5 },
     timeout: 120000,
     parser:
      HTTPParser {
        '0': [Function: parserOnHeaders],
        '1': [Function: parserOnHeadersComplete],
        '2': [Function: parserOnBody],
        '3': [Function: parserOnMessageComplete],
        '4': [Function: bound onParserExecute],
        _headers: [],
        _url: '',
        _consumed: true,
        socket: [Circular],
        incoming: [IncomingMessage],
        outgoing: null,
        maxHeaderPairs: 2000,
        onIncoming: [Function: bound parserOnIncoming] },
     on: [Function: socketOnWrap],
     _paused: false,
     _httpMessage: [Circular],
     [Symbol(asyncId)]: 8,
     [Symbol(lastWriteQueueSize)]: 0,
     [Symbol(timeout)]:
      Timeout {
        _called: false,
        _idleTimeout: 120000,
        _idlePrev: [TimersList],
        _idleNext: [TimersList],
        _idleStart: 6746,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(unrefed)]: true,
        [Symbol(asyncId)]: 9,
        [Symbol(triggerId)]: 8 },
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  _header:
   'HTTP/1.1 200 OK\r\nX-Powered-By: Express\r\nAccess-Control-Allow-Origin: *\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 22631\r\nETag: W/"5867-c3Fodr1eSCA3vlKX+kDMgudDONQ"\r\nDate: Wed, 26 Aug 2020 18:14:27 GMT\r\nConnection: keep-alive\r\n\r\n',
  _onPendingData: [Function: bound updateOutgoingData],
  _sent100: false,
  _expect_continue: false,
  req:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: null,
        ended: true,
        endEmitted: false,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: true,
        readableListening: false,
        resumeScheduled: false,
        emitClose: true,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: true,
        decoder: null,
        encoding: null },
     readable: true,
     _events: {},
     _eventsCount: 0,
     _maxListeners: undefined,
     socket:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: [TCP],
        _parent: null,
        _host: null,
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: true,
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: [Server],
        _server: [Server],
        timeout: 120000,
        parser: [HTTPParser],
        on: [Function: socketOnWrap],
        _paused: false,
        _httpMessage: [Circular],
        [Symbol(asyncId)]: 8,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]:
         Timeout {
           _called: false,
           _idleTimeout: 120000,
           _idlePrev: [TimersList],
           _idleNext: [TimersList],
           _idleStart: 6746,
           _onTimeout: [Function: bound ],
           _timerArgs: undefined,
           _repeat: null,
           _destroyed: false,
           [Symbol(unrefed)]: true,
           [Symbol(asyncId)]: 9,
           [Symbol(triggerId)]: 8 },
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0 },
     connection:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: [TCP],
        _parent: null,
        _host: null,
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: true,
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: [Server],
        _server: [Server],
        timeout: 120000,
        parser: [HTTPParser],
        on: [Function: socketOnWrap],
        _paused: false,
        _httpMessage: [Circular],
        [Symbol(asyncId)]: 8,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]:
         Timeout {
           _called: false,
           _idleTimeout: 120000,
           _idlePrev: [TimersList],
           _idleNext: [TimersList],
           _idleStart: 6746,
           _onTimeout: [Function: bound ],
           _timerArgs: undefined,
           _repeat: null,
           _destroyed: false,
           [Symbol(unrefed)]: true,
           [Symbol(asyncId)]: 9,
           [Symbol(triggerId)]: 8 },
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0 },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers:
      { host: 'localhost:5000',
        connection: 'keep-alive',
        'user-agent':
         'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36',
        accept: '*/*',
        origin: 'http://localhost:3000',
        'sec-fetch-site': 'same-site',
        'sec-fetch-mode': 'cors',
        'sec-fetch-dest': 'empty',
        referer: 'http://localhost:3000/',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-US,en;q=0.9',
        'if-none-match': 'W/"5868-+iRV2Q1kdgam9TbgiDgKID9Vs1s"' },
     rawHeaders:
      [ 'Host',
        'localhost:5000',
        'Connection',
        'keep-alive',
        'User-Agent',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36',
        'Accept',
        '*/*',
        'Origin',
        'http://localhost:3000',
        'Sec-Fetch-Site',
        'same-site',
        'Sec-Fetch-Mode',
        'cors',
        'Sec-Fetch-Dest',
        'empty',
        'Referer',
        'http://localhost:3000/',
        'Accept-Encoding',
        'gzip, deflate, br',
        'Accept-Language',
        'en-US,en;q=0.9',
        'If-None-Match',
        'W/"5868-+iRV2Q1kdgam9TbgiDgKID9Vs1s"' ],
     trailers: {},
     rawTrailers: [],
     aborted: false,
     upgrade: false,
     url: '/places/restaurants+near%20me',
     method: 'GET',
     statusCode: null,
     statusMessage: null,
     client:
      Socket {
        connecting: false,
        _hadError: false,
        _handle: [TCP],
        _parent: null,
        _host: null,
        _readableState: [ReadableState],
        readable: true,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: true,
        allowHalfOpen: true,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: [Server],
        _server: [Server],
        timeout: 120000,
        parser: [HTTPParser],
        on: [Function: socketOnWrap],
        _paused: false,
        _httpMessage: [Circular],
        [Symbol(asyncId)]: 8,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]:
         Timeout {
           _called: false,
           _idleTimeout: 120000,
           _idlePrev: [TimersList],
           _idleNext: [TimersList],
           _idleStart: 6746,
           _onTimeout: [Function: bound ],
           _timerArgs: undefined,
           _repeat: null,
           _destroyed: false,
           [Symbol(unrefed)]: true,
           [Symbol(asyncId)]: 9,
           [Symbol(triggerId)]: 8 },
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0 },
     _consuming: false,
     _dumped: false,
     next: [Function: next],
     baseUrl: '',
     originalUrl: '/places/restaurants+near%20me',
     _parsedUrl:
      Url {
        protocol: null,
        slashes: null,
        auth: null,
        host: null,
        port: null,
        hostname: null,
        hash: null,
        search: null,
        query: null,
        pathname: '/places/restaurants+near%20me',
        path: '/places/restaurants+near%20me',
        href: '/places/restaurants+near%20me',
        _raw: '/places/restaurants+near%20me' },
     params: { query: 'restaurants+near me' },
     query: {},
     res: [Circular],
     route:
      Route { path: '/places/:query', stack: [Array], methods: [Object] } },
  locals: {},
  statusMessage: 'OK',
  statusCode: 200,
  [Symbol(isCorked)]: false,
  [Symbol(outHeadersKey)]:
   { 'x-powered-by': [ 'X-Powered-By', 'Express' ],
     'access-control-allow-origin': [ 'Access-Control-Allow-Origin', '*' ],
     'content-type': [ 'Content-Type', 'application/json; charset=utf-8' ],
     'content-length': [ 'Content-Length', '22631' ],
     etag: [ 'ETag', 'W/"5867-c3Fodr1eSCA3vlKX+kDMgudDONQ"' ] } }
_http_outgoing.js:470
    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/Users/tyleranyan/Documents/api-practice/places/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/tyleranyan/Documents/api-practice/places/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/tyleranyan/Documents/api-practice/places/node_modules/express/lib/response.js:267:15)
    at Request.request [as _callback] (/Users/tyleranyan/Documents/api-practice/places/proxy/server.js:25:11)
    at Request.self.callback (/Users/tyleranyan/Documents/api-practice/places/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/Users/tyleranyan/Documents/api-practice/places/node_modules/request/request.js:1154:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/Users/tyleranyan/Documents/api-practice/places/node_modules/request/request.js:1076:12)
evan
  • 5,443
  • 2
  • 11
  • 20
tganyan
  • 603
  • 3
  • 9
  • 23
  • So I understand that this URL `https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=REF&key=KEY` does work for you on the browser, but not on your proxy server? – evan Aug 26 '20 at 16:50
  • What line does the above error point to, and what's the value you get as a result when console logging it? Also can you show us the network call (its headers and results and code status) you're making when checking dev tools for example? – evan Aug 26 '20 at 16:51
  • Thanks for the response! To answer your first question, yes, pasting the url into the browser gets the desired result (and I'm copying it directly from a console log that's a direct copy of the template string in the request). As for your second comment, I made a few updates to my post (under "UPDATE" in bold) that I hope provide what you're looking for (I'm less experienced in some of these areas, so I'm hoping I didn't misunderstand what you're asking for). – tganyan Aug 26 '20 at 18:25
  • Thank you, I see the problem, writing my answer now in hopes it helps you. – evan Aug 27 '20 at 14:55

1 Answers1

1

The problem here is that the request library appears to have been deprecated. If you switch to another one such as axios, the following code based on your own works without problem:

const express = require('express')
const axios = require('axios')

const url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=YOUR_API_KEY"

const getData = async (url) => {
  try {
    const response = await axios.get(url)
    const data = response.data
    console.log('data', response.data)
  } catch (error) {
    console.log('error', error)
  }
}

const app = express()
const port = 3000

app.get('/', async (req, res) => {
  res.send(await getData(url))
})

app.listen(port, () => {})

Output:

Response GET / status=200
"data"
"����\u0000\u0010JFIF\u0000\u0001\u00…01b`J+]�Ǥ�%�„c����8�\u001fb\u0017/��..."

Also the response is an image; don't json it in the backend. There's the client-side service though.

evan
  • 5,443
  • 2
  • 11
  • 20
  • 1
    This makes a lot of sense, thanks! I'll try and put it into action later today when I have time and update here. – tganyan Aug 27 '20 at 15:54
  • 1
    Ok, I thought it made a lot of sense but definitely struggling so far to get the correct data returned to the front end. Will continue working through it, but so far I've been unable to get any of the data to properly return to the front end. Thanks again for your help with this, will update when I've been able to get it to work. – tganyan Aug 27 '20 at 21:15
  • 1
    UPDATE: Everything seems to be working on the server side (the issue was a simple one, I forgot to include "async" in the get request). I appear to be getting the image data back in the front end, but I'm not really sure how to parse it or what to do with it so I'll have to work through that. Thanks for all the help! – tganyan Aug 27 '20 at 22:06
  • 1
    If you want to show it in the front i'd recommend you go with the client side service i linked in my answer. E.g. see related thread https://stackoverflow.com/questions/39271759/show-image-from-google-api-place-photo-response – evan Aug 28 '20 at 03:05
  • And you're welcome happy to have been of assistance :) – evan Aug 28 '20 at 03:05
  • 1
    Oh i just remembered my own accepted answer to a similar question. Please see https://stackoverflow.com/a/57425962 – evan Aug 28 '20 at 03:09