Tips for ensuring that BingMaps is fully loaded in Aurelia

I have been attempting to integrate BingMaps into an Aurelia Single Page Application (SPA). My approach involved adding the BingMaps script tag to the Head section of the Index page, like so:

<head>
    <meta charset="utf-8">
    <script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=release'></script>
</head>

Additionally, I have created a Map template and Map controller structured as follows:

map.html

<template>
    <div id='mainMap' style='width: 100vw; height: 100vh;'></div>
</template>

map.ts

export class Map
{
    map:Microsoft.Maps.Map;

    attached(){
        this.map = new Microsoft.Maps.Map('#mainMap', {credentials: myKey});
        this.map.setView({center: new Microsoft.Maps.Location(45.093,14.114), zoom:15});
    }
} 

Currently, I am utilizing the Aurelia Typescript WebPack Skeleton for my application. Upon running the application and clicking on the Map menu link, everything works correctly and the map is displayed. However, if I refresh the browser, Aurelia throws an exception:

Unhandled rejection TypeError: Cannot read property 'prototype' of null at k () // additional error lines here...

This issue indicates that the Map script may not be fully loaded before the Attached method in the Map controller executes. How can I instruct Aurelia to wait for the map script to load completely before proceeding with the execution of the Attached method?

Answer №1

If you're looking to load a map script, you have a couple of options at your disposal. Firstly, you can simply add a callback parameter to the script URL and specify the name of a function to execute once the map script has finished loading:

<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=LoadMap' async defer></script>

It's important to note that specifying the release branch for the map control is unnecessary as it defaults to that setting.

Alternatively, if you prefer not to use the callback method, another approach involves checking for the availability of the Microsoft.Maps namespace and waiting until it becomes accessible. This can be achieved by implementing timeouts, as demonstrated below:

function LoadMap(){
    if(typeof Microsoft !== undefined && typeof Microsoft.Maps !== undefined){
        //Execute your map loading code here
    } else {
        setTimeout(LoadMap, 100);
    }
}

Answer №2

To ensure proper functionality, it is essential to wait for two key events. Firstly, you must allow the script to load, followed by waiting for the Microsoft script to load its API. This can be achieved using the callback parameter. I suggest utilizing jQuery for the initial task, as it can easily be converted into a promise. Here's an example:

const _BING_MAPS_URL = 'https//www.bing.com/api/maps/mapcontrol?';
const _DEFAULT_CONFIG = $.params({
  key: 'yourkey',
  callback: 'globalScopedCallback'
});

loadBingMaps() {
  const callbackInvoked = new Promise((resolve) => {
     window.globalScopedCallback = resolve;
  });
  const scriptLoaded = new Promise((resolve, reject) => {
    $.getScript(_BING_MAPS_URL + _DEFAULT_CONFIG).done(resolve).fail(reject);
  });
  // Additional promises loading modules and other necessary items can be added here.
  return Promise.all([callbackInvoked, scriptLoaded]);
}
// Once everything is loaded, execute your desired actions
loadBingMaps().then(doYourAwesomeStuff);

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

I continue to encounter the same error while attempting to deliver data to this form

Encountering an error that says: TypeError: Cannot read properties of null (reading 'persist') useEffect(() => { if (edit) { console.log(item) setValues(item!); } document.body.style.overflow = showModal ? "hidden ...

Issue with reading the current length of an array object in a while loop in Angular 6

After successfully splitting an array into parts, I decided to add some filters to only include the items in the list that have an action status of (4). However, I encountered a problem where the while loop couldn't read the length of the array. This ...

Self-referencing type alias creates a circular reference

What causes the discrepancy between these two examples? type Foo = { x: Foo } and this: type Bar<A> = { x: A } type Foo = Bar<Foo> // ^^^ Type alias 'Foo' circularly references itself Aren't they supposed to have the same o ...

Error: Webpack hot module replacement cannot locate the specified file or directory

I am currently using Ubuntu on Windows. I recently cloned the react-redux-starter-kit repository. However, I encountered a similar issue with the react-redux-universal-hot-example as well as with my own projects. Upon running npm install followed by npm s ...

Spacing Problem with Title Tooltips

After using the padEnd method to ensure equal spacing for the string and binding in the title, I noticed that the console displayed the string perfectly aligned with spaces, but the binded title appeared different. Is it possible for the title to support s ...

Unable to assign to 'routerLinkActiveOptions' as it is not recognized as a valid property

Lately, I've delved into the world of angular 8. While configuring the routing module in my app.component.html file, everything was smooth sailing except for achieving an ActiveTab using routerLinkActiveOptions on my li item. https://i.sstatic.net/9Z ...

Yet another error: TS2511 - Unable to instantiate an abstract class

My issue is very similar to the one mentioned in this thread: Typescript: instance of an abstract class, however, there are some distinctions. If it is indeed a duplicate problem, I would appreciate a clear explanation as I am currently unable to resolve t ...

Prep yourself for an incoming response from an object in Angular 9

Greetings, this is my debut post here so my apologies if I am not following the correct procedures. As a novice in Angular with no experience in synchronism, I kindly request that any explanation be kept as simple as possible. I am currently working with ...

How to make a POST request with custom headers in NestJS

Has anyone successfully sent a Post request using Nestjs to a 3rd party API that needs authorization through a client-key and secret? I am looking for guidance on how to include headers in the request, ideally using axio's HttpService. ...

Adding React with TypeScript to an existing ASP.NET Core MVC application: A step-by-step guide

Can anyone suggest a reliable method to integrate react components (typescript) in the form of .tsx files into my asp.net core mvc .cshtml pages? I've been encountering issues trying to make it work successfully. Any insights or advice would be greatl ...

Access the keys of a Flow object type within your codebase

Is it feasible to extract keys from a Flow object type definition within the application code (in other words, are Flow type definitions reflected in any way in the runtime code)? Scenario: type Props = { userID: string, size: number | PhotoSize, s ...

Some elements that fit the criteria of 'number | function' are not callable at all

Consider a basic function like this: export const sum = (num?: number) => { const adder = (n: number) => { if (!n) { return num; } num = (num && num + n) || n; return adder; }; return a ...

Exploring Functions in Object Literal Notation in TypeScript: Why is the Context of 'this' Assigned as Type 'any'?

It appears that the question has been posed before, but my search yielded no results. The issue at hand seems rather straightforward. TypeScript integrates well with object literal notation, however, when methods are defined within, it struggles to handle ...

Typescript function incorrectly returns Protractor's "element.all" output as Promise<string> instead of Promise<string[]>

Kindly review the code snippet provided below. The function getAllGroupIds() is designed to return an array of IDs belonging to "group" elements. The goal is to retrieve all the group-ids both before and after a test action, in order to compare them. Howe ...

The most effective approach to creating linked observable subscriptions

How can we refactor this code reactively using RxJS for better performance? let profileInformation; updateProfile() { let token; let profileId = 1; this.userService.getAccessToken() .pipe( tap((res) => { //as I need it multipl ...

Highchart in ionic 2 not displaying

https://i.sstatic.net/q2CPR.png I inserted code for a highchart on my webpage, but it's not appearing I followed instructions from this video tutorial https://www.youtube.com/watch?v=FSg8n5_uaWs Can anyone help me troubleshoot this issue? This is ...

Adding a Component in Ionic 3: Step-by-Step Guide

When I run this command: ionic generate component my-component It creates the following folder structure: components my-component my-component.ts my-component.scss my-component.html components.module.ts Now, I want to i ...

Can Webpack function without npm?

I recently embarked on a new project that involves React for the frontend and Java Play for the backend. Surprisingly, I am not using nodejs or npm in this setup. When attempting to import a component that I developed, I encountered an error stating "Refe ...

Diving into Angular Typescript: Understanding the [object Object] in HTML

One of my todos requires the following input: todo.ts: import { TodoTag } from "./todo-tag-custom"; export class Todo { ... tags: TodoTag[]; } todo.html <tr *ngFor="let todo of todosFiltered()"> <td>{{todo.tags | json ...

Formik's handleChange function is causing an error stating "TypeError: null is not an object (evaluating '_a.type')" specifically when used in conjunction with the onChange event in DateInput

When using the handleChange function from Formik with the DateInput component in "semantic-ui-calendar-react", I encountered an error upon selecting a date. https://i.stack.imgur.com/l56hP.jpg shows the console output related to the error. AddWishlistFor ...