Unusual Interactions between Angular and X3D Technologies

There is an unusual behavior in the x3d element inserted into an Angular (version 4) component that I have observed.

The structure of my Angular project is as follows:

x3d_and_angular/
    app/
        home/
            home.component.css
            home.component.html
            home.component.ts
            index.ts
        viewer/
            viewer.component.css
            viewer.component.html
            viewer.component.ts
            index.ts
        app.component.html
        app.component.ts
        app.module.ts
        app.routing.ts
        main.ts
    app.css
    index.html
    package.json
    red_box.x3d
    sysytemjs.config.js

I included the x3dom library in both package.json and sysytemjs.config.js.

This is how my index.html looks like:

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>X3D and Angular Integration</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- bootstrap css -->
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
    <link rel='stylesheet' type='text/css' href='http://www.x3dom.org/download/x3dom.css'>

    <!-- application css -->
    <link href="app.css" rel="stylesheet" />

    <!-- polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
        System.import('app').catch(function (err) { console.error(err); });
    </script>

    <script>
        function show_inline_url(){
            console.log(document.getElementById("inline_element"));
        }
    </script>
</head>
<body>
    <app>Loading ...</app>
</body>
</html>

The X3D file (red_box.x3d) that displays a small red box has the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
<x3d>
  <head>
    <meta name="title"/>
  </head>
  <Scene>
    <Shape id="shape_id">
        <appearance> 
            <material diffuseColor='1 0 0'></material>
        </appearance>       
        <box></box> 
    </Shape>
  </Scene>
</x3d>

Here is the code for the home component:

  • home.component.html:

    <div>
        <a [routerLink]="['/viewer']">X3D Viewer</a>
    </div>
    
  • home.component.ts:

    import { Component, OnInit } from '@angular/core';
    
    @Component({
        moduleId: module.id,
        templateUrl: 'home.component.html',
        styleUrls: ['home.component.css'],
    })
    
    export class HomeComponent{
        constructor() { }
    }
    

The issue arises in the viewer component. Below are the files associated with this component:

  • viewer.component.html:

    <div>
        <x3d width='600px' height='400px'> 
            <scene>
                <inline id="inline_element" [url]="x3d_filename"> </inline>
            </scene>
            <a [routerLink]="['/']"><span>BACK</span></a>
        </x3d> 
    </div>
    
  • viewer.component.ts:

    import { Component, OnInit } from '@angular/core';
    
    declare var System: any;
    
    @Component({
        moduleId: module.id,
        templateUrl: 'viewer.component.html',
        styleUrls: ['viewer.component.css'],
    })
    
    export class ViewerComponent implements OnInit{
    
        x3d_filename: string = "red_box.x3d";
    
        constructor() { 
            this.importX3d();
        }
    
        ngOnInit(){
            if(window["x3dom"] != undefined){
                window["x3dom"].reload();
            }
        }
    
        importX3d():void{        
            System.import('x3dom').then(() => { 
                console.log('loaded x3d');
            }).catch((e:any) => {
                console.warn(e);
            })
        }
    }
    

The routing of my Angular application goes from the home component to the viewer component and vice versa. These routes are defined in the app.routing.ts file:

import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/index';
import { ViewerComponent } from './viewer/index';

const appRoutes: Routes = [
    { path: '', component: HomeComponent},
    { path: 'viewer', component: ViewerComponent},

    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

export const routing = RouterModule.forRoot(appRoutes);

Upon refreshing the website, when accessing the viewer component for the first time, the scene appears empty. However, subsequent visits to this component through routing (without refreshing) result in the box being rendered inside the scene.

Replacing the inline tag in the viewer.component.html file with

<inline url="red_box.x3d"> </inline>
eliminates this issue (the box is rendered even on the first visit after a refresh).

If anyone has suggestions on how to resolve this peculiar behavior, I would greatly appreciate it. I am relatively new to Angular and web development, so any assistance is welcomed. Thank you.

Answer №1

Following Sara Jones's advice, the issue can be resolved by substituting [url] with [attr.url] in the document viewer.component.html. Furthermore, alterations need to be made to the file viewer.component.ts, and it should now read as shown below:

import { Component, AfterViewInit, OnDestroy } from '@angular/core';

declare var System: any;

@Component({
    moduleId: module.id,
    templateUrl: 'viewer.component.html',
    styleUrls: ['viewer.component.css'],
})

export class ViewerComponent implements AfterViewInit, OnDestroy{

    x3d_filename: string = "blue_sphere.x3d";

    constructor() { 
        this.importX3d();
    }

    ngAfterViewInit(){
        if(window["x3dom"] != undefined){
            window["x3dom"].reload();
        }
    }

    importX3d():void{        
        System.import('x3dom').then(() => { 
            console.log('loaded x3d');
        }).catch((e:any) => {
            console.warn(e);
        })
    }

    ngOnDestroy(){
        System.delete(System.normalizeSync('x3dom'));
    }

}

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 animation of the splash screen in Angular is quite jarring and lacks fluidity

I am experiencing some issues with my angular splash screen animation. It works perfectly when there is no activity in the background, but when I simulate a real-life application scenario, the animation becomes stuttered, choppy, or sometimes does not anim ...

What is the best way to set a boolean value for a checkbox in a React project with Typescript?

Currently, I am working on a project involving a to-do list and I am facing an issue with assigning a boolean value to my checkbox. After array mapping my to-dos, the checkbox object displays 'on' when it is unchecked and a 'Synthetic Base E ...

Receiving NULL data from client side to server side in Angular 2 + Spring application

I'm currently working on a project that involves using Angular 2 on the client side and Spring on the server side. I need to send user input data from the client to the server and receive a response back. However, I'm encountering an issue where ...

The attribute 'XXX' is not found within the type 'IntrinsicAttributes & RefAttributes<any>'

My coding hobby currently involves working on a React website using TypeScript. I recently came across a free Material UI template and decided to integrate it into my existing codebase. The only challenge is that the template was written in JavaScript, cau ...

Using the map operator in an Angular 7 application with rxjs

Despite successfully compiling my code and having everything work perfectly, I encountered an error message in my IDE (Visual Studio Code) that is preventing me from deploying my app using ng build --prod: ERROR in src/app/training/training.service.ts(6 ...

What is the best way for me to determine the average number of likes on a post?

I have a Post model with various fields such as author, content, views, likedBy, tags, and comments. model Post { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt id String @id @default(cuid()) author U ...

Learn the process of uploading files with the combination of Angular 2+, Express, and Node.js

Need help with uploading an image using Angular 4, Node, and Express with the Multer library. Check out my route.js file below: const storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, 'uploads') }, filename: fun ...

What is the mechanism behind angular2's spa routing functioning seamlessly without the need for the hash character in the url?

During my experience with the Angular2 "Tour of Heroes" tutorial, I made an interesting observation about how their single page application router functions without a trailing hash symbol (#) in the URL. This differs from the Kendo SPA router, which typica ...

What is the definition of the style directive?

While I have a good amount of experience with Angular, there are still areas where my knowledge falls short. I've been exploring the directive that allows for setting specific styles on an element, like so: <div [style.color]="'red'"> ...

Observable subscription not updating HTML with changes

My challenge is passing an object to the Object Model using a shared service to an already loaded component. Even though I receive data after subscribing, it does not reflect in the HTML view. <div *ngFor="let emp of emps" class="card&q ...

How to use the Angular 7 CLI in a programmatic way

My goal is to set up a server that can launch an Angular 7 app. Another scenario where this capability would be useful is for more advanced generation tasks, such as adding multiple files directly after generating an Angular project. const angularClient = ...

When the keyboard appears, the Ionic 2 form smoothly slides upwards

I am currently working with the most recent version of Ionic 2. In my code, I have a <ion-content padding><form></form></ion-content> containing a text input. However, when attempting to enter text on an Android device, the keyboard ...

Customizing the styling of buttons in Highcharts is disabled when in full screen mode

I've integrated highcharts into my Angular application and included a custom button inside the chart to navigate users to another page. However, I encountered an issue when trying to fullscreen the chart using the export menu. The position of the cus ...

Optimizing Angular 2+ performance with a custom minification of the

I've taken note of the cautions regarding avoiding pipes for ordering/sorting. While I understand the concerns with impure pipes, I'm not entirely clear on the issue with minification. The documentation and various posts highlight the potential ...

What is the best way to configure Angular viewProviders when using an NgForm in a unit test?

One of the challenges I faced was with an Angular 16 component that required the form it will be placed inside as input. The solution came from using the viewProviders property, which I discovered through a helpful response to a question I had asked previo ...

A step-by-step guide to showcasing dates in HTML with Angular

I have set up two datepickers in my HTML file using bootstrap and I am attempting to display a message that shows the period between the first selected date and the second selected date. The typescript class is as follows: export class Datepicker { ...

Angular 2 Demonstrate Concealing and Revealing an Element

I am currently facing an issue with toggling the visibility of an element based on a boolean variable in Angular 2. Below is the code snippet for showing and hiding the div: <div *ngIf="edited==true" class="alert alert-success alert-dismissible fade i ...

Troubleshooting Angular: Unidentified property 'clear' error in testing

I've implemented a component as shown below: <select #tabSelect (change)="tabLoad($event.target.value)" class="mr-2"> <option value="tab1">First tab</option> <op ...

Issue encountered with Angular when making a post request, whereas there is no problem with J

I am attempting to send a post request containing information to a token Uri. This information should result in receiving an access token back from the token Uri once authorization is granted. I have successfully implemented this on a plain HTML page using ...

Activate TypeScript EMCAScript 6 support for Cordova projects in Visual Studio

I am interested in utilizing the async/await feature of TypeScript in my VS2015 Cordova project. I have updated "target": "es6" in tsconfig.json Although there are no errors shown in intellisense, I encounter the following error while building the project ...