Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 1 and Angular 2 Hybrid Application Routing Issue (angular component not displaying)

I have an Angular 1 and Angular 2 hybrid application that was set-up using the following guides, Upgrading from AngularJS and Migrating Angular 1 Application to Angular 2. My root component looks like this:

import { NgModule, Component } from '@angular/core';
import { RouterModule, UrlHandlingStrategy } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';
import { RouterUpgradeInitializer } from '@angular/router/upgrade';
import { MyModule } from './Mymodule/my-module';

export class Ng1Ng2UrlHandlingStrategy implements UrlHandlingStrategy {
    shouldProcessUrl(url: any) {
        return url.toString().startsWith("/Mymodule");
    }

    extract(url: any) {
        return url;
    }

    merge(url: any, whole: any) {
        return url;
    }
}

@Component({
    selector: 'root-component',
    template: `
    <router-outlet></router-outlet>
    <div class="ng-view"></div>
  `
})
export class RootComponent { }

@NgModule({
    imports: [
        BrowserModule,
        UpgradeModule,
        MyModule,

        RouterModule.forRoot([])
    ],
    providers: [
        { provide: UrlHandlingStrategy, useClass: Ng1Ng2UrlHandlingStrategy }
    ],
    bootstrap: [RootComponent],
    declarations: [RootComponent]
})
export class Ng2AppModule {
    constructor(public upgrade: UpgradeModule) { }
}

And my "main.ts" is the following:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { setUpLocationSync } from '@angular/router/upgrade';
import { Ng2AppModule } from "./Angular2/app.rootcomponent";

// This is the entry point for the AngularJS/Angular hybrid application.
// It bootstraps the Angular module 'Ng2AppModule', which in turn bootstraps
// the AngularJS module 'angular1App'.
platformBrowserDynamic().bootstrapModule(Ng2AppModule).then(ref => {
    const upgrade = (<any>ref.instance).upgrade;
    // bootstrap angular1
    upgrade.bootstrap(document.body, ['angular1App']);
    setUpLocationSync(upgrade);
});

The module 'MyModule' follows:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { TestDataListComponent } from './testdata-list.component';

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'Mymodule', children: [
                    { path: 'testdata', component: TestDataListComponent }
                ]
            }
        ])
    ],
    declarations: [TestDataListComponent ]
})
export class MyModule {

}

And 'TestDataListComponent' component is very simple:

import { Component } from '@angular/core';

@Component({
    selector: 'test-data',
    templateUrl: 'App/Angular2/MyModule/testdata-list.component'.html'
})
export class TestDataListComponent{

}

The way I am linking to the Angular 2 component is in a main menu HTML page. The relevant code is the following:

<li id="main-menu" class="menu-top-level" ng-mouseover="cur = 'mymodule'">        
    <a ng-reflect-router-link="/Mymodule/testdata" href="#/Mymodule/testdata">
        MyModule
        <span>
            <i class="fa fa-check-square fa-2x"></i>
        </span>
    </a>
</li>

The problem I am experiencing is that clicking on the link above takes me to a blank view, i.e. the component TestDataListComponent is not displayed. However if I replace the following line in my main Angular 2 module, i.e. Ng2AppModule:

RouterModule.forRoot([])

with:

RouterModule.forRoot([], { useHash: true, initialNavigation: false })

component TestDataListComponent shows up fine, but then when I attempt to navigate back to an Angular 1 component, by clicking on a link, the page is blank and what I noticed is that the URL in my browser window looks like this:

http://localhost:60813/#/

while it should looks like this:

http://localhost:60813/#/myclients

If I click on the link a second time, the URL is correct and the Angular 1 component is displayed fine.

The relevant portion of my Angular 1 module angular1App is:

angular.module("angular1App",
["ngRoute",
 "myInterceptorService",
 "ngStorage",
 "ngAnimate",
 "ui.bootstrap",
 "ngResource",
 "SignalR",
 "ui.select",
 "ngSanitize"])
.config([
    "$routeProvider", "$httpProvider", function($routeProvider, $httpProvider) {

        $httpProvider.interceptors.push("myInterceptorService");

        $routeProvider
            .when('/myclients',
            {
                title: "Client Data",
                controller: "clientDataCtrl",
                templateUrl: "/App/Common/Views/clientData.html"
            })

What is the problem here? Why is either my Angular 2 or Angular 1 component now showing up?

like image 725
lukegf Avatar asked Jul 10 '17 20:07

lukegf


2 Answers

Your problem with component appears to be here:

import { Component } from '@angular/core';

@Component({
    selector: 'test-data',
    templateUrl: 'App/Angular2/MyModule/testdata-list.component'.html'
})
export class TestDataListComponent{

}

You need to add correct templateUrl strin

like image 108
Antonio Ribeiro Avatar answered Oct 21 '22 23:10

Antonio Ribeiro


The solution was provided by brandonroberts on the Angular github. For details, see this issue https://github.com/angular/angular/issues/18832

Excerpt from solution: "The way setupLocationSync provides the URL to the router for navigating doesn't work correctly with hash-based routing. What I did was tweak the source from the setupLocationSync to pass the URL from the hash to navigate with. This way the Router will handle navigating both scenarios correctly."

See the Plunker in the issue above for details.

like image 36
lukegf Avatar answered Oct 22 '22 00:10

lukegf