Angular Cesium.js Integration: Exploring the Power of Injection Tokens

Currently, I'm exploring how to utilize the cesium.js library in an angular-friendly manner to continue working with typescript. While following tutorials on integrating 3rd party libraries, I am attempting to inject dependencies using a dependency token. Unfortunately, my code is not compiling and I encountered the following errors:

ERROR in ....../node_modules/cesium/Build/Cesium/Cesium.js (557,23102): Unreachable code detected.
ERROR in ....../node_modules/cesium/Build/Cesium/Cesium.js (557,24518): Unreachable code detected.
ERROR in ....../node_modules/cesium/Build/Cesium/Cesium.js (559,26990): Unreachable code detected.

I have set up a stack blitz containing all the necessary code for reference, but due to limitations handling dependencies, it may produce the error mentioned above. Please feel free to copy the code into your environment.

Access my stack blitz demo, and also check out the tutorial that guided me through.

For further details, here are the raw files available for reference.

This project has been created using angular-cli

The initial step involved running npm install --save cesium

cesium.lib.ts

import { InjectionToken } from '@angular/core';
import * as cesiumLib from '../../../node_modules/cesium/Build/Cesium/Cesium.js';

export const cesiumToken = new InjectionToken('cesium');
export const cesium = cesiumLib;
export type Cesium = typeof cesiumLib;
export * from 'cesium';

gobe.module.ts

import { GlobeComponent } from './globe.component';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import * as cesiumLib from './cesium.lib';

@NgModule({
  declarations: [
    GlobeComponent
  ],
  imports: [
  ],
  providers: [
    { provide: cesiumLib.cesiumToken, useValue: cesiumLib.cesium}
  ]
})

export class GlobeModule {}

globe.component.ts

import { cesium, cesiumToken } from './cesium.lib';
import { Component, Inject, OnInit, ViewEncapsulation, AfterViewInit, ViewChild, ElementRef } from '@angular/core';

@Component({
    selector: 'app-globe',
    templateUrl: './globe.component.html',
    styleUrls: ['./globe.component.css'],
    encapsulation: ViewEncapsulation.None
})
export class GlobeComponent implements OnInit, AfterViewInit {

    constructor( @Inject(cesiumToken) private cesium: any) {
    }

    ngAfterViewInit() {
        this.viewer = new Cesium.viewer('cesiumContainer')
    }

}

globe.component.html

<div id="cesiumContainer"></div>

globe.component.css

@import url(../Build/Cesium/Widgets/widgets.css);

#cesiumContainer {
    width: 100%;
    height: 720px;
    margin: 0; padding: 0;
    overflow: hidden;
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowJs": true,
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",

    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  }
}

.angular-cli.json snippet

"styles": [
        "../node_modules/bootstrap/dist/css/bootstrap.min.css",
        "../node_modules/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css",
        "styles.css",
        "../node_modules/font-awesome/css/font-awesome.css",
        "../node_modules/cesium/Build/Cesium/Widgets/widgets.css"
      ],
      "scripts": [
          "../node_modules/jquery/dist/jquery.min.js",
          "../node_modules/bootstrap-switch/dist/js/bootstrap-switch.min.js",
          "../node_modules/cesium/Build/Cesium/Cesium.js"

___UPDATE______

Following suggestions made by @Justin Shwartzenberger, even though the compiler runs successfully, the page continues loading indefinitely until it eventually fails. Any insights on resolving this issue? It occurs once I add the script and css to the .angular-cli.json file.

Answer №1

To include the necessary third-party CSS and JS files, add the following code in the first object of the apps array in the .angular-cli.json file:

"styles": [
  "styles.css",
  "../node_modules/cesium/Build/Cesium/Widgets/widgets.css"
],
"scripts": [
  "../node_modules/cesium/Build/Cesium/Cesium.js"
],

In your cesium.lib.ts file, simply create an InjectionToken for Cesium by including:

import { InjectionToken } from '@angular/core';
export const cesiumToken = new InjectionToken('cesium');

Add the declaration for Cesium in your typings.d.ts to let TypeScript recognize it:

declare var Cesium: any;

In your app.module.ts, set up the injection token and assign its value to the global variable created by the third-party library:

import {cesiumToken} from './cesium.lib';

. . .

providers: [
  { provide: cesiumToken, useValue: Cesium }
],

. . .

Lastly, in your app.component.ts, inject the token value into a class field and utilize the API provided by Cesium:

. . .

constructor( @Inject(cesiumToken) private cesium: any) {}

. . .

ngAfterViewInit() {
  this.viewer = new this.cesium.Viewer('cesiumContainer');
}

. . .

You can extend this setup by creating typings for the Cesium library and adding more encapsulation as needed.

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

Is there a way for me to modify this carousel so that it only stops when a user hovers over one of the boxes?

I am currently working to modify some existing code to fit my website concept. One aspect I am struggling with is how to make the 'pause' function activate only when a user hovers over one of the li items, preventing the carousel from looping end ...

Update the Azure AD token with a personalized JWT token

We have developed an Angular 11 frontend application with a .NET 5 backend API. Our system offers two login options: 1. Basic authentication using user details stored in our system with JWT token generation, and 2. Azure AD authentication. During the Azu ...

Transferring user input data from Angular 2 to Slim PHP endpoint

Help needed with parsing form-data in Slim PHP. How can I put form-data into an array in Slim PHP? I have tried different methods but the data always gets kicked out in one array with no specific way to target the form data. Any suggestions would be helpf ...

strictBindCallApply causing issues when working with generic parameters

Take a look at this slightly contrived code snippet: export function evaluate<T>(this: { value: T }) { return this.value; } class SomeClass { value: ''; constructor() { const result = evaluate.call(this); } } You might notice ...

What occurs when socket.io events are not properly handled?

Is socket.io ignoring or dropping messages? I am asking this because there is a client with multiple states, each having its own set of socket handlers. The server notifies the client of a state change and then sends messages specific to that state. Howeve ...

Include data in the ajax call only if the value is not null

I have a question regarding this specific div element: <div class='additional_comments'> <input type="text" id='additional_comments_box', maxlength="200"/> </div> Occasionally, this div may appear on the page dep ...

Is it feasible to utilize a variable as a function within JavaScript programming?

I've been diving into the world of express.js and came across these statements. const express = require('express'); const app = express(); It's intriguing how we can call the variable "express" as a function by simply adding parenthese ...

Experiencing a JSONP issue with an 'Access-Control-Allow-Origin' error

When working with PHP, I often use the following code to echo JSONP formatted data: echo $_GET['callback'] . '('.json_encode($arr).')'; In my AngularJS (JavaScript) code, I make a GET request like this: $http.get('http ...

What is the best way to choose a file path for the saveAs() function in JavaScript or TypeScript?

Q1: What is the method for defining the path when using the saveAs() function in JavaScript? After downloading a file, I want to be able to specify a path like: C:\Users\file-\projectName\src\assets\i18n\en.json const b ...

Mocha test failing to trigger function execution

I've been developing an Express.js application that includes a feature for creating appointments with a post request. This feature involves retrieving and saving data from a third-party API, followed by sending updated API data in the subsequent reque ...

Tips for importing modules in React JS/Next JS + Typescript as 'components/filename' rather than '../../../components/filename'

Is there a way to import pages, components, and containers directly using syntax like 'components/filename' or '@components/filename', rather than having to specify the full path to the parent folder such as '../../components/filen ...

Trouble with communication between a pair of Angular2 components

Looking to share a value between 2 Angular2 components? The code for my App component is: <app-header></app-header> <router-outlet></router-outlet> <app-footer></app-footer> The typescript code for my login componen ...

What is the best way to use regular expressions in JavaScript to pull out a date value from a string?

I am working with a string in this format: var value = "/Date(1454187600000+0300)/". From this, I need to extract a date format like 1/30/2016. Currently, I have the following code snippet: var value = "/Date(1454187600000+0300)/"; // I need to extract f ...

Cannot access an object's property within templates if imported from a separate class

I recently started working with Angular and encountered a problem where Angular16 is unable to display the properties of an object when defined in an external class. Take a look at the example below. In the code snippet below, I have created a class to st ...

Is it possible to manipulate elements within an overflow container using JavaScript/jQuery when using the HTML style "overflow:hidden"?

My <div> has a styling of style="overflow:hidden" and the size of the <body> is fixed, intended as a multi-screen display without a user interface. Is there a method to access these "invisible" elements to identify the first one that exceeds t ...

What is the best way to create a function that can disable console.log and be imported into other React files for easy access?

Here is the content of my static.js file: var Helper = { console.log: function(){ }, Login: function(){ var name; var password; //rest of the code } } module.exports = Helper; Now, in my test.js file: var Helper ...

**Finding the Index of a Table Row in Vue-Tables-2**

Recently, I came across some vue code that utilizes vue-tables-2. The table in question is quite simple and looks like this... <v-client-table :data="myRows" :columns="columns" :options="options"> <div slot=" ...

React - Can you explain the purpose of the callback function in the forceUpdate method?

The React documentation mentions that the forceUpdate method includes a parameter called callback. Does this function in any way resemble the second parameter found in setState, which is executed after setting state? Or does it serve a different purpose? ...

Encountering MIME type discrepancies in NGINX maintenance configurations while working with Angular?

I have set up a maintenance configuration in nginx that I switch out for my production one. This config is designed to load an index.html file based on an Angular SPA and redirect to the /maintenance page within the application. When I use try_files /inde ...

Rearrange list items by dragging and dropping

Here is the HTML and TypeScript code I have implemented for dragging and dropping list items from one div to another: HTML: <div class="listArea"> <h4> Drag and Drop List in Green Area: </h4> <ul class="unstyle"> <l ...