Accessing the Bing Maps REST services from various JavaScript frameworks

NOTE: An updated version of this article can be found in the Microsoft Maps Blog.
https://www.microsoft.com/en-us/maps/news/accessing-the-bing-maps-rest-services-from-various-javascript-frameworks

Bing Maps for Enterprise has many valuable REST services for location-aware applications, like routing, geocoding addresses, calculating an isochrone, and many more. However, on the Bing Maps forums, we often encounter developers who have difficulty accessing the Bing Maps API REST services using different JavaScript frameworks such as jQuery, Angular, React, or Blazor. 

One common point of confusion is that passing in a REST service request URL into the address bar of a browser works, however passing that same URL into an AJAX method in JavaScript does not. 

As a refresher, AJAX (short for "Asynchronous JavaScript and XML") allows web pages to be updated asynchronously. This is done by exchanging small amounts of data (today, mainly JSON) with the server, making it possible to update just parts of a webpage without reloading the entire page. 

This tutorial post will take a deep dive into accessing the Bing Maps API services using different JavaScript frameworks. 

Cross-Origin Resource Sharing (CORS) 

Before using any API calls, we first need to understand what Cross-Origin Resource Sharing (CORS) means. CORS is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. Modern browsers block any API call that does not come from the same domain as a security percussion. Luckily the Bing Maps API allows API calls cross-domain by sending the HTTP-header Access-Control-Allow-Origin: *

Using Pure JavaScript

The Fetch API provides a modern JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network. As a result, you can make HTTP requests (using GET, POST, and other methods), download, and upload files.

This kind of functionality was previously achieved using XMLHttpRequest(). The Fetch API provides a better alternative that can be easily used by other technologies such as Service Workers. The Fetch API also provides a single logical place to define other HTTP-related concepts such as CORS and extensions to HTTP. The first implementation of XMLHttpRequest() shipped in 1999 as an IE5.0 ActiveX component.  Microsoft developed XMLHttpRequest() primarily as a browser-based alternative to the Outlook email client. An XMLHttpRequest() looks like this:

function xhrData(url) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true); 
    xhr.onreadystatechange = function () { 
        if (xhr.readyState == 4 && xhr.status == 200) { 
            var json = JSON.parse(xhr.responseText); 
            console.debug(json); 
        } 
    } 
    xhr.send()
}

The Fetch API is clean, elegant, more straightforward to understand, and heavily used in modern web applications and frameworks today. To start a request, call the special function fetch()

const response = await fetch(resource[, options]);

fetch() starts a request and returns a promise. When the request is completed, the promise is resolved with the response object. If the request fails due to some network problems, the promise is rejected. The async/await syntax fits great with fetch() because it simplifies the work with promises. 

For example, let's use the Bing Maps API to Find a Location by Query for "1 Microsoft Way, Redmond, Wa, 98052":

var data = await fetchData('http://dev.virtualearth.net/REST/v1/Locations/1%20Microsoft%20Way%20Redmond%20WA%2098052?o=json&key=YOUR_BING_MAPS_KEY'); 

async function fetchData(url) { 

    const response = await fetch(url); 

    if (!response.ok) { 
        const message = `An error has occured: ${response.status}`; 
        throw new Error(message); 
    } 

    const json = await response.json(); 
    return json; 
} 

Tip: When working with address data, encoding the URL is important! Check out our Bing Maps API Best Practices for helpful information.

Using jQuery

JQuery (http://jquery.com) is a very popular JavaScript framework that makes it easier to developer JavaScript that works across different browsers. jQuery provides a three of different functions to make HTTP GET requests to services:

  • jQuery.ajax ($.ajax)
  • jQuery.get ($.get)
  • jQuery.getJSON ($.getJSON)

The jQuery.get and jQuery.getJSON functions are meant to be simplified versions of the jQuery.ajax function but have less functionality.

We can take the same example from our pure Javascript and modify it to leverage jQuery and see how it simplifies the code.

var url = 'http://dev.virtualearth.net/REST/v1/Locations/1%20Microsoft%20Way%20Redmond%20WA%2098052?o=json&key=YOUR_BING_MAPS_KEY';
var data = await $getJSON(url);

console.log(data);


Using Angular

Angular is a TypeScript-based, free and open-source web application framework.

To perform HTTP requests in Angular, we need the HttpClient. This service is available as an injectable class, with methods to perform HTTP requests. HttpClient is Angular's mechanism for communicating with a remote server over HTTP. 

Make HttpClient available everywhere in the application in two steps. First, add it to the root AppModule (src/app/app.module.ts) by importing it:

import { HttpClientModule } from '@angular/common/http'

Then, while still in the AppModule, add HttpClientModule to the imports array:

@NgModule ({
   imports: [HttpClientModule,],
})

Next you can use the HttpClient in your application like this, we use the same Bing Maps API example to Find a Location by Query

this.httpClient.request('GET', 'http://dev.virtualearth.net/REST/v1/Locations/1%20Microsoft%20Way%20Redmond%20WA%2098052?o=json&key=YOUR_BING_MAPS_KEY', { responseType: 'json' }); 

See also the tutorial: Angular - Get data from a server 

Using React

React is a free and open-source front-end JavaScript library for building user interfaces based on UI components. To request data from an API you can use any AJAX library you like with React. Some popular ones are Axios, jQuery, and the browser built-in Fetch API (see above). You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.

componentDidMount() {

fetch('http://dev.virtualearth.net/REST/v1/Locations/1%20Microsoft%20Way%20Redmond%20WA%2098052?o=json&key=YOUR_BING_MAPS_KEY')
   .then(res => res.json())
   .then(
      (result) => {
         this.setState({ isLoaded: true, items: result.resourceSets });
      },
      // Note: it's important to handle errors here
      // instead of a catch() block so that we don't swallow
      // exceptions from actual bugs in components
.
      (error) => {
         this.setState({ isLoaded: true, error });
      }
   )
}

Using Blazor

Blazor is a free, open-source web framework that enables developers to create web apps using C# and HTML. The advantage of being a C# developer is that you can use the same programming skills and code for the client and the backend. In addition, Blazor can run on the client as WebAssembly or on the backend as a Server.

Blazor WebAssembly apps call web APIs using a preconfigured HttpClient service, which is focused on making requests back to the server of origin. Additional HttpClient service configurations for other web APIs can be created in developer code. Requests are composed using Blazor JSON helpers or with HttpRequestMessage. Requests can include Fetch API option configuration.

Blazor Server apps call web APIs using HttpClient instances, typically created using IHttpClientFactory. For guidance that applies to Blazor Server, see Make HTTP requests using IHttpClientFactory in ASP.NET Core. For a complete tutorial see Call a web API from an ASP.NET Core Blazor app

Conclusion

Accessing the Bing Maps REST services from various JavaScript frameworks is not that difficult if you use the proper methods for your framework of choice. However, we recommend that you also read the Understanding Bing Maps Transactions page and the Bing Maps REST Services Docs.