title: Trying to get location change to capture a static image with Google Street View Static API
body: <p>I am trying to build an application using Ionic2 that allows a user to load a <a href="https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewPanorama" rel="nofollow noreferrer">StreetViewPanorama</a> object via the Google Street View Static API. Once the view is loaded, a user should be able to manipulate the street view in any way they choose (move away from the original position, zoom, etc.). Upon completion of this task, a user will capture a static image of the final street view.</p>
  <p>My difficulty is arising when I attempt to capture the photo of the new street view location. I am trying to use Google's <a href="https://developers.google.com/maps/documentation/streetview/intro" rel="nofollow noreferrer">documentation on static image generation to achieve this</a>. Unfortunately, I am unable to get reference the attributes of a Panorama object after the object is created. I am relatively new to Javascript, so bear with me.</p>
  <p>To generate the street view panorama, I run the following functions (starting at the bottom with <code>initMap()</code>):</p>
  <pre><code> /**
    * Creates the map options for panorama generation. This includes adjusting the coordinate
    * position of a user to the nearest available street view. Following creation of the settings,
    * it generates the street view on a user's device.
    *
    * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
    *                     the corresponding latitude and longitude respectively
    */
    generatePanorama(userLocation): void {
      var streetviewService = new google.maps.StreetViewService;
      streetviewService.getPanorama({
        location: userLocation,
        preference: google.maps.StreetViewPreference.NEAREST,
        radius: 100},
        function(result, status) {
          console.log(&quot;Adjusted latitude: &quot;, result.location.latLng.lat(),
                      &quot;\nAdjusted longitude: &quot;, result.location.latLng.lng());
          new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
            position: result.location.latLng,
            pov: {heading: 165, pitch: 0},
            zoom: 1
          });
        });
    }
  
  
    /**
    * Uses a device's native geolocation capabilities to get the user's current position
    *
    * @return a JSON object whose keys are 'lat' and 'lng' and whose calues are the corresponding
    *         latitude and longitude respectively
    */
    getLocation(callback): void {
      Geolocation.getCurrentPosition().then((position) =&gt; {
        console.log(&quot;Latitude: &quot;, position.coords.latitude, &quot;\nLongitude: &quot;, position.coords.longitude);
        callback({lat: position.coords.latitude, lng: position.coords.longitude});
      }).catch((error) =&gt; {
        console.log('Error getting location', error);
      });
    }
  
   /**
    * Initialize a Google Street View Panorama image
    */
    initMap(): void {
      this.getLocation(this.generatePanorama);
    }
  </code></pre>
  <p>I am creating a panorama, as shown above, with the code,</p>
  <pre><code>new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
        position: result.location.latLng,
        pov: {heading: 165, pitch: 0},
        zoom: 1
      });
  </code></pre>
  <p>I am unable to assign this object to an instance variable for use in the following two functions:</p>
  <pre><code> /**
    * Generates a URL to query the Google Maps API for a static image of a location
    *
    * @param lat the latitude of the static image to query
    * @param lng the longitude of the static image to query
    * @param heading indicates the compass heading of the camera
    * @param pitch specifies the up or down angle of the camera relative to the street
    * @return a string that is the URL of a statically generated image of a location
    */
    generateStaticMapsURL(lat, lng, heading, pitch): string {
      var url = &quot;https://maps.googleapis.com/maps/api/streetview?size=600x300&amp;location=&quot;;
      url += lat + &quot;,&quot; + lng;
      url += &quot;&amp;heading=&quot; + heading;
      url += &quot;&amp;pitch=&quot; + pitch;
      url += &quot;&amp;key=SECRET_KEY&quot;;
      return url;
    }
  
    openShareModal() {
      console.log(&quot;Final Latitude: &quot;, this.panorama.getPosition().lat());
      console.log(&quot;Final Longitude: &quot;, this.panorama.getPosition().lng());
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().heading);
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().pitch);
      let myModal = this.modalCtrl.create(ShareModalPage);
      myModal.present();
    }
  </code></pre>
  <p>When I try to assign the object to an instance variable either directly or through a helper function I get an <code>UnhandledPromiseRejectionWarning</code> and nothing works. So how exactly can I extract things like location, heading, and pitch from the street view object after it is created?</p>
  <p>Thank you for your help!</p>
  <p><strong>Update 1:</strong> The program is currently building fine. I assign an instance variable of <code>panorama: any;</code> and then proceed to try and update the variable using the following function and assignment.</p>
  <pre><code>/**
    * Creates the map options for panorama generation. This includes adjusting the coordinate
    * position of a user to the nearest available street view. Following creation of the settings,
    * it generates the street view on a user's device.
    *
    * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
    *                     the corresponding latitude and longitude respectively
    */
    generatePanorama(userLocation): void {
      var streetviewService = new google.maps.StreetViewService;
      streetviewService.getPanorama({
        location: userLocation,
        preference: google.maps.StreetViewPreference.NEAREST,
        radius: 100},
        function(result, status) {
          console.log(&quot;Adjusted latitude: &quot;, result.location.latLng.lat(),
                      &quot;\nAdjusted longitude: &quot;, result.location.latLng.lng());
          this.panorama = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
            position: result.location.latLng,
            pov: {heading: 165, pitch: 0},
            zoom: 1
          });
        });
    }
  </code></pre>
  <p>When I do this and then subsequently try to use the <code>panorama</code> variable in another function, it seems to think <code>panorama</code> is an empty variable. Additionally, the panorama map doesn't load at all! Here is the second function I try to use the panorama variable in.</p>
  <pre><code>openShareModal() {
      console.log(&quot;Final Latitude: &quot;, this.panorama.getPosition().lat());
      console.log(&quot;Final Longitude: &quot;, this.panorama.getPosition().lng());
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().heading);
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().pitch);
      let myModal = this.modalCtrl.create(ShareModalPage);
      myModal.present();
    }
  </code></pre>
  <p><strong>UPDATE 2:</strong> Posting the entire chunk of my code for assistance.</p>
  <pre><code>import { Component, ViewChild } from '@angular/core';
  import { IonicPage, NavController, NavParams, ViewController, ModalController } from 'ionic-angular';
  import { ShareModalPage } from '../share-modal/share-modal';
  import { Geolocation } from 'ionic-native';
  declare var google;
  
  /**
   * Generated class for the StreetViewModalPage page.
   *
   * See https://ionicframework.com/docs/components/#navigation for more info on
   * Ionic pages and navigation.
   */
  
  @IonicPage()
  @Component({
    selector: 'page-street-view-modal',
    templateUrl: 'street-view-modal.html',
  })
  
  export class StreetViewModalPage {
  
    @ViewChild('map') mapElement;
    map: any;
    panorama: any;
  
    constructor(public navCtrl: NavController, public navParams: NavParams,
                public viewCtrl: ViewController, public modalCtrl: ModalController) {}
  
    ionViewDidLoad() {
      console.log('ionViewDidLoad StreetViewModalPage');
      this.initMap();
    }
    
  
    /**
    * Creates the map options for panorama generation. This includes adjusting the coordinate
    * position of a user to the nearest available street view. Following creation of the settings,
    * it generates the street view on a user's device.
    *
    * @param userLocation a JSON object whose keys are 'lat' and 'lng' and whose values are
    *                     the corresponding latitude and longitude respectively
    */
    generatePanorama(userLocation): void {
      var streetviewService = new google.maps.StreetViewService;
      streetviewService.getPanorama({
        location: userLocation,
        preference: google.maps.StreetViewPreference.NEAREST,
        radius: 100},
        function(result, status) {
          console.log(&quot;Adjusted latitude: &quot;, result.location.latLng.lat(),
                      &quot;\nAdjusted longitude: &quot;, result.location.latLng.lng());
          this.panorama = new google.maps.StreetViewPanorama(document.getElementById('street-view'), {
            position: result.location.latLng,
            pov: {heading: 165, pitch: 0},
            zoom: 1
          });
        });
    }
  
  
    /**
    * Uses a device's native geolocation capabilities to get the user's current position
    *
    * @return a JSON object whose keys are 'lat' and 'lng' and whose calues are the corresponding
    *         latitude and longitude respectively
    */
    getLocation(callback): void {
      Geolocation.getCurrentPosition().then((position) =&gt; {
        console.log(&quot;Latitude: &quot;, position.coords.latitude, &quot;\nLongitude: &quot;, position.coords.longitude);
        callback({lat: position.coords.latitude, lng: position.coords.longitude});
      }).catch((error) =&gt; {
        console.log('Error getting location', error);
      });
    }
  
    /**
    * Initialize a Google Street View Panorama image
    */
    initMap(): void {
      this.getLocation(this.generatePanorama);
    }
  
    /**
    * Generates a URL to query the Google Maps API for a static image of a location
    *
    * @param lat the latitude of the static image to query
    * @param lng the longitude of the static image to query
    * @param heading indicates the compass heading of the camera
    * @param pitch specifies the up or down angle of the camera relative to the street
    * @return a string that is the URL of a statically generated image of a location
    */
    generateStaticMapsURL(lat, lng, heading, pitch): string {
      var url = &quot;https://maps.googleapis.com/maps/api/streetview?size=600x300&amp;location=&quot;;
      url += lat + &quot;,&quot; + lng;
      url += &quot;&amp;heading=&quot; + heading;
      url += &quot;&amp;pitch=&quot; + pitch;
      url += &quot;&amp;key=XXXXXXXXXXXX&quot;; // TODO : Make private
      return url;
    }
  
    openShareModal() {
      console.log(&quot;Final Latitude: &quot;, this.panorama.getPosition().lat());
      console.log(&quot;Final Longitude: &quot;, this.panorama.getPosition().lng());
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().heading);
      console.log(&quot;Final Heading:&quot;, this.panorama.getPov().pitch);
      let myModal = this.modalCtrl.create(ShareModalPage);
      myModal.present();
    }
  
  }
  </code></pre>
  <p>And the corresponding HTML...</p>
  <pre><code>&lt;ion-content&gt;
     &lt;div #map id=&quot;street-view&quot; style=&quot;height:100%; width:100%;&quot;&gt;&lt;/div&gt;
     &lt;button ion-button style=&quot;position: absolute; top: 5px; right: 5px; z-index: 1;&quot; (click)=&quot;openShareModal()&quot; large&gt;&lt;ion-icon name=&quot;camera&quot;&gt;&lt;/ion-icon&gt;&lt;/button&gt;
  &lt;/ion-content&gt;
  </code></pre>