Learning to implement Angular's two-way binding with the directionsService.route() function in Google Maps

Check out my Angular Component

export class MapsComponent implements OnInit {

  @ViewChild('googleMap') gmapElement: any;
  map: google.maps.Map;  
  data = "initialized";

  ngOnInit() {
    var directionsService = new google.maps.DirectionsService;
    var directionsDisplay = new google.maps.DirectionsRenderer;

      var map =  new google.maps.Map(this.gmapElement.nativeElement, {
            zoom: 7,
            center: {lat: 41.85, lng: -87.65}
      });
      directionsDisplay.setMap(map);
      directionsService.route({
          origin: "terrell hills, tx",
          destination: "alamo heights, tx",
          travelMode: google.maps.TravelMode.DRIVING
        },  (response, status) => {
          if (String(status) === 'OK') {
            directionsDisplay.setDirections(response);
            this.data = "I've been updated by directionsService";
            
          } else {
            alert('Directions request failed due to ' + status);
      }
    });
  }

Here is how it looks in my Template

<span>{{data}}</span> <!-------------this always shows "initialized"-------------->

Can anyone explain why the main class member 'data' is not being updated?

  • The value of alert(this.data) before
    this.data = "I'm modified in directionsService";
    is initialized
  • The value of alert(this.data) after
    this.data = "I'm modified in directionsService";
    is I'm modified in directionsService
  • However, the main class member data remains unchanged.
  • I tried creating another function
    function testFunc(x:any) { this.data = x; }
    . Calling this.testFunc("some text") from ngOnInit() successfully updates data, but calling it within directionsService.route does not work
  • Assigning var self = this outside the function and using
    self.data = "some text with self"
    also did not solve the issue.

Any help on this would be greatly appreciated. Thank you.

Answer №1

There seems to be a problem with detecting the change, as it is happening outside of the Angular framework within the Google Directions callback function. There are several ways you can approach this issue, listed below from easiest to more challenging.

Option 1: Force Change Detection

constructor(private ref: ChangeDetectorRef){}
....
if (String(status) === 'OK') {
    directionsDisplay.setDirections(response);
    this.data = "I have been updated in directionsService";
    this.ref.detectChanges();
...

Option 2: Run in Angular2 Zone

constructor(private ngZone:NgZone) {}
...
this.ngZone.run(() => {
    -- Perform directions query here
});
...

Option 3: Wrap the directions call in an observable

const directionsObservable = Observbable.create(observer => {
    directionsService.route({
      origin: "terrell hills, tx",
      destination: "alamo heights, tx",
      travelMode: google.maps.TravelMode.DRIVING
    },  (response, status) => {
      if (String(status) === 'OK') {
        directionsDisplay.setDirections(response);
        observer.next("I have been updated in directionsService");
      } else {
        alert('Directions request failed due to ' + status);
  }
});
directionsObservable.subscribe(text => this.data = text);

I've provided a basic example of how an observable can be used in this scenario. It's recommended to move the directions call to a separate service and implement the observable method there for better organization.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The element is implicitly of type 'any' due to the fact that a 'string' expression cannot be used to index the Phaser type

I've seen this question before, but I'm still struggling to find a solution that fits my situation. In my file, I have defined certain values and want to loop through them. The issue arises in the following part of the code: preloadImages(){ ...

Add jQuery to a JavaScript document

Apologies for any language barriers, English is not my first language... I currently have a my_js.js file that is included in all my asp pages. However, I now need to incorporate jQuery into this specific page without directly adding script tags like < ...

Is the functionality of defineProperty for elements malfunctioning on iOS6?

There seems to be an issue with JavaScript's defineProperty and __defineSetter not working on elements in iOS6. It functions correctly on all other browsers and earlier versions of iOS. Does anyone have more information on this? <input id='Bu ...

Is it possible to send emails from a local server to Gmail, Yahoo, or Rediff?

Currently, I am developing a feature that allows users to send emails to any recipient including Yahoo and Gmail. Below is the code snippet for my contact form: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1 ...

MongoDB does not treat aggregate match pipeline as equal to in comparisons

I've been tackling an aggregate pipeline task for MongoDB where I need to retrieve items that do not have a specific user ID. Despite my efforts, I'm struggling to get it right. I attempted using $not, $ne, and $nin in various ways but couldn&ap ...

Beginner in Typescript - Exploring ways to verify an interface using an index

When working with a list of operations in a database, each operation may have a unique set of variables that need to be passed. To make adding new operations easier, I decided to store the interfaces within a list structure like this: const operation = { ...

The 'admin' attribute is not found in the 'Object' data type

I have been facing this issue for quite some time now. The backend API response is indicating that a certain property does not exist, even though it clearly does. My Angular application suddenly started showing 18 errors today, and I am at a loss on how ...

Animating circles with CSS to display percentages

Currently, I have a circle displaying text in the center as shown in this fiddle (JSFIDDLE http://jsfiddle.net/874jgh4v/2/). Now, my requirements are: I want to animate the outer white border based on a percentage. For example, if the percentage is 50% ...

Calculate the total of the provided HTML element's content with Angular version 1.x.x

Looking to calculate the total of all values in table cells with ng-model. However, it is treating the values as strings instead of numbers. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <ta ...

Would it be unwise to create a link to a database directly from the client?

If I want to connect my React app to Snowflake all client-side, are there any potential issues? This web app is not public-facing and can only be accessed by being part of our VPN network. I came across this Stack Overflow discussion about making API cal ...

Using Angular to Deliver Content from a Folder

Is there a way to display a list of documents from the same folder where my Angular application is hosted, along with individual download links for each document? If so, how can this be achieved? ...

Storing executable scripts in HTML5 LocalStorage allows for the dynamic creation

As I work on a hybrid app with its own local HTML and JS files, there are times when I need to load additional small executable JS scripts and CSS from the server. Currently, I achieve this by using $.getScript, which has been working well. In order to ma ...

Automatically navigate the user to a different webpage in Node.js upon completion of a function within a POST request

I have a nodejs script where the user starts at localhost:3000/index. When the code runs, the page /index displays a form. Upon clicking the submit button, the user is redirected to localhost:3000/process. In the script.js file, there is a POST request tha ...

Troubleshooting issue: Dropdown menu malfunctioning after using replaceWith() and appendTo()

I could really use some assistance. Admittedly, my knowledge of php, js, jquery, and similar languages is limited. I am currently working on a small web application where users fill out a form with specific requests, the data is then stored in a database, ...

Troubleshooting issue: matTooltip malfunctioning in *ngFor loop after invoking Angular's change

The matTooltip in the component below is rendering correctly. The overlay and small bubble for the tooltip are rendered, but the text is missing (even though it's present in the HTML when inspecting in the browser) and it isn't positioned correct ...

Searching for a user's first name and last name in mongoDB and retrieving the entire object

My goal is to locate my users in the database by searching for both their first and last names, and then retrieving the complete object of each user. However, my current code only returns the concatenated `firstName` and `lastName` as `name` along with the ...

Is there a way to have the collapsible content automatically expanded upon loading?

I came across a tutorial on w3school (https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_collapsible_symbol), which demonstrates collapsible content hidden by default. The code snippet from the link is provided below. Can someone assist me in cha ...

The marker.js 2 documentation states that integrating marker.js with React poses compatibility issues when using next.js

I have followed the documentation for using this in my next.js app, but unfortunately, it's not functioning as expected. There are no errors, but nothing happens when I click on the image. It appears that this library may not be compatible with Next. ...

In the realm of React Native, an error arises when attempting to access 'this._nativeModule.isBluetoothEnabled', as the reference to null prevents it from

Recently, I delved into working with react native and attempted to incorporate react-native-bluetooth-classic into my project. The URL for the API overview can be found here. However, I encountered an issue that has me stuck: "TypeError: null is not ...

Fetch information from the Anilist API

I'm currently working on a small Next.js application and I attempted to fetch data from an API (). My goal is to display a collection of Anime covers. In order to achieve this, I had to implement GraphQL. Initially, I wanted to display the names of s ...