5

[EDIT] I've created a demo repository with this error: https://github.com/SamanthaAdrichem/hybrid-lazy-load-angularjs-injector-error

We've followed the instructions, and all runs fine on normal hybrid, but adding lazy loading fails with the strange error above, and always implemented ui router the way the docs say (as you can see in the code below).

When loading the app all is fine, but when then clicking onto a lazy-loaded route we get the error

Transition Rejection($id: 0 type: 6, message: The transition errored, detail: Error: Trying to get the AngularJS injector before it being set.)

I've tried the solutions listed here

https://github.com/ui-router/angular-hybrid/issues/93

https://github.com/ui-router/angular-hybrid/issues/150

https://github.com/ui-router/angular-hybrid/issues/395

https://github.com/ui-router/sample-app-angular-hybrid/issues/10

But none of these solve it. We don't use ng serve because that crashes with random memory issues (probably also due to hybrid), and we need to proxy to a login page, but the login page and our project would be running on the same port, which isn't possible. So that needs some refactoring in the backend.

It does sometimes load a new chunk file depending on what page i'm going to. But mostly i get this error.

Funny part is, in the page i'm testing we're not using any hybrid code. Basically we're are no longer upgrading any code, we're only downgrading some observers to open modals of the older pages.

These are the versions we're running

"@angular/cli": "9.1.7",
"@angular/animations": "9.0.7",
"@angular/common": "9.0.7",
"@angular/compiler": "9.0.7",
"@angular/core": "9.0.7",
"@angular/forms": "9.0.7",
"@angular/localize": "9.0.7",
"@angular/platform-browser": "9.0.7",
"@angular/platform-browser-dynamic": "9.0.7",
"@angular/router": "9.0.7",
"@angular/upgrade": "9.0.7",
"@uirouter/angular": "6.0.1",
"@uirouter/angular-hybrid": "10.0.1",
"@uirouter/angularjs": "1.0.26",
"@uirouter/core": "6.0.5",
"@uirouter/rx": "0.6.5",

Below the detailed error and some code, don't know what else to share or what i can safely share.

Any suggestions on how to debug this would be lovely!

detailed error

stateService.ts?8765:537 Transition Rejection($id: 0 type: 6, message: The transition errored, detail: Error: Trying to get the AngularJS injector before it being set.)
$defaultErrorHandler @ stateService.ts?8765:537
eval @ stateService.ts?8765:379
processQueue @ angular.js?21b1:17963
eval @ angular.js?21b1:18037
$digest @ angular.js?21b1:19176
eval @ upgrade_module.ts?423f:268
schedulerFn @ event_emitter.ts?938d:96
SafeSubscriber.__tryOrUnsub @ Subscriber.ts?face:266
SafeSubscriber.next @ Subscriber.ts?face:208
Subscriber._next @ Subscriber.ts?face:140
Subscriber.next @ Subscriber.ts?face:100
Subject.next @ Subject.ts?4a10:71
EventEmitter.emit @ event_emitter.ts?938d:86
checkStable @ ng_zone.ts?9664:224
onHasTask @ ng_zone.ts?9664:314
ZoneDelegate.hasTask @ zone.js?d135:440
ZoneDelegate._updateTaskCount @ zone.js?d135:462
Zone._updateTaskCount @ zone.js?d135:284
Zone.runTask @ zone.js?d135:205
drainMicroTaskQueue @ zone.js?d135:601
Promise.then (async)
scheduleMicroTask @ zone.js?d135:584
ZoneDelegate.scheduleTask @ zone.js?d135:410
onScheduleTask @ zone.js?d135:294
ZoneDelegate.scheduleTask @ zone.js?d135:400
Zone.scheduleTask @ zone.js?d135:231
Zone.scheduleMicroTask @ zone.js?d135:251
scheduleResolveOrReject @ zone.js?d135:881
resolvePromise @ zone.js?d135:819
eval @ zone.js?d135:739
webpackJsonpCallback @ app.js?v=1591962370205:26
(anonymous) @ 0.js?v=1591962370205:1
stateService.ts?8765:538 Error: Trying to get the AngularJS injector before it being set.
    at injectorFactory (angular1_providers.ts?397c:22)
    at _callFactory (ng_module.ts?c185:163)
    at _createProviderInstance (ng_module.ts?c185:74)
    at resolveNgModuleDep (ng_module.ts?c185:74)
    at _callFactory (ng_module.ts?c185:163)
    at _createProviderInstance (ng_module.ts?c185:74)
    at resolveNgModuleDep (ng_module.ts?c185:74)
    at _callFactory (ng_module.ts?c185:163)
    at _createProviderInstance (ng_module.ts?c185:74)
    at resolveNgModuleDep (ng_module.ts?c185:74)
    at NgModuleRef_.get (refs.ts?151c:134)
    at applyNgModule (lazyLoadNgModule.ts?7cfb:143)
    at applyModule (lazyLoadNgModule.ts?7cfb:79)
    at ZoneDelegate.invoke (zone.js?d135:384)
    at Object.onInvoke (ng_zone.ts?9664:224)
    at ZoneDelegate.invoke (zone.js?d135:384)
    at Zone.run (zone.js?d135:143)
    at eval (zone.js?d135:891)
    at ZoneDelegate.invokeTask (zone.js?d135:419)
    at Object.onInvokeTask (ng_zone.ts?9664:224)
    at ZoneDelegate.invokeTask (zone.js?d135:419)
    at Zone.runTask (zone.js?d135:188)
    at drainMicroTaskQueue (zone.js?d135:601)

Our main.ts

// Bootstrapping
import {enableProdMode, NgModuleRef, NgZone, ViewEncapsulation} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {dom, library} from '@fortawesome/fontawesome-svg-core';
import {UIRouter, UrlService} from '@uirouter/core';
import {icons} from 'app/scripts/modules/app-layout/icons/icons';
import 'bootstrap/dist/js/bootstrap.js';
import 'expose-loader?jQuery!expose-loader?$!jquery';
import 'expose-loader?moment!moment';
import 'scripts/app.module';
import 'scripts/homer';
import 'scripts/static.assets';
import {AppModule} from 'src/app/app.module';
import {environment} from 'src/environments/environment';

library.add(...icons);
dom.watch();

// If ready
if (/comp|inter|loaded/.test(document.readyState)) {
    bootstrap();
} else {
    document.addEventListener('DOMContentLoaded', bootstrap);
}

function bootstrap(): void {

    if (true === environment.production) {
        enableProdMode();
    }

    platformBrowserDynamic().bootstrapModule(
        AppModule,
        [{
            defaultEncapsulation: ViewEncapsulation.None
        }]
    ).then((platformRef: NgModuleRef<AppModule>) => {
        // Initialize the Angular Module
        // get() the UIRouter instance from DI to initialize the router
        const urlService: UrlService = platformRef.injector.get(UIRouter).urlService;

        // Instruct UIRouter to listen to URL changes
        platformRef.injector.get<NgZone>(NgZone).run(() => {
            urlService.listen();
            urlService.sync();
        });
    });
}

Our app.module.ts

import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import {DoBootstrap, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {setAngularJSGlobal, UpgradeModule} from '@angular/upgrade/static';
import {MissingTranslationHandler, TranslateModule, TranslateService} from '@ngx-translate/core';
import {UIRouterUpgradeModule} from '@uirouter/angular-hybrid';
import * as angular from 'angular';
import {AngularModalObserver} from 'hybrid/modal/modal.observer';
import {AdvertiserLastTransactionsModalObserver} from 'hybrid/modals/advertiser-last-transactions-modal.observer';
import {CampaignsModalObserver} from 'hybrid/modals/campaigns-modal.observer';
import {GoogleModalObserver} from 'hybrid/modals/google-modal.observer';
import {InvoiceModalObserver} from 'hybrid/modals/invoice-modal.observer';
import {PublisherLastTransactionsModalObserver} from 'hybrid/modals/publisher-last-transactions-modal.observer';
import {TicketsModalObserver} from 'hybrid/modals/tickets-modal.observer';
import {AngularTranslationsObserver} from 'hybrid/translations/translations.observer';
import {DatepickerModule} from 'ngx-bootstrap/datepicker';
import {ModalModule} from 'ngx-bootstrap/modal';
import {PagesAdminModule} from 'pages/admin/admin.a2.module';
import {GdprCleanupModule} from 'pages/publisher/account/gdpr-cleanup/gdpr-cleanup.module';
import {LayoutEventsObserver} from 'scripts/modules/app-layout/layout-events.observer';
import {ElementsExternalLinkModule} from 'scripts/modules/elements/external-link.a2/external-link.module';
import {ElementsPageHeaderModule} from 'scripts/modules/elements/page-header/page-header.module';
import {LocalizationMissingTranslationsService} from 'scripts/modules/localization/missing-translations.service';
import {AdminRoutingModule} from 'src/app/admin/admin-routing.module';
import {AdvertiserModule} from 'src/app/advertiser/advertiser.module';
import {AccountModel} from 'src/app/core/auth/account.model';
import {AuthObserver} from 'src/app/core/auth/auth.observer';
import {AuthService} from 'src/app/core/auth/auth.service';
import {IdentityService} from 'src/app/core/auth/identity.service';
import {TokenModel} from 'src/app/core/auth/token.model';
import {CoreModule} from 'src/app/core/core.module';
import {UserProfileModel} from 'src/app/core/data/backend/user/profile/user-profile.model';
import {AuthInterceptor} from 'src/app/core/interceptors/auth.interceptor';
import {CacheInterceptor} from 'src/app/core/interceptors/cache.interceptor';
import {GetAsPostInterceptor} from 'src/app/core/interceptors/get-as-post.interceptor';
import {GetMultiInterceptor} from 'src/app/core/interceptors/get-multi.interceptor';
import {LocalizationService} from 'src/app/core/localization/localization.service';
import {LeadgenerationModule} from 'src/app/leadgeneration/leadgeneration.module';
import {EnergyNlModule} from 'src/app/publisher/pages/widgets/widgets/energy/energy-nl/energy-nl.module';
import {PublisherModule} from 'src/app/publisher/publisher.module';

setAngularJSGlobal(angular);

@NgModule({
    exports: [
        TranslateModule
    ],
    imports: [
        AdminRoutingModule,
        AdvertiserModule,
        BrowserModule,
        BrowserAnimationsModule,
        CoreModule,
        DatepickerModule.forRoot(),
        ElementsExternalLinkModule,
        ElementsPageHeaderModule,
        GdprCleanupModule,
        HttpClientModule,
        LeadgenerationModule,
        ModalModule.forRoot(),
        PagesAdminModule,
        PublisherModule,
        TranslateModule.forRoot({
            missingTranslationHandler: {
                provide: MissingTranslationHandler,
                useClass: LocalizationMissingTranslationsService
            }
        }),
        UIRouterUpgradeModule.forRoot(),
        UpgradeModule,

        // These modules are needed here during hybrid
        EnergyNlModule, // This one can be removed once the entire widget pages has been migrated
    ],
    // All providers you need in AngularJS
    providers: [
        // These observers need to be here, it's required outside of it's own scope.
        // Angular creates a new instance based on the require module level
        AdvertiserLastTransactionsModalObserver,
        AngularModalObserver,
        AngularTranslationsObserver,
        AuthObserver,
        CampaignsModalObserver,
        GoogleModalObserver,
        InvoiceModalObserver,
        LayoutEventsObserver,
        PublisherLastTransactionsModalObserver,
        TicketsModalObserver,

        // Request interceptors, might be able to move them to the actual modules, but those are generated
        { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: GetAsPostInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: GetMultiInterceptor, multi: true },
    ]
})
export class AppModule implements DoBootstrap {

    constructor(
        private angularTranslationsObserver: AngularTranslationsObserver,
        private identityService: IdentityService,
        private authObserver: AuthObserver,
        private authService: AuthService,
        private localizationService: LocalizationService,
        private translateService: TranslateService,
        private upgrade: UpgradeModule
    ) {}

    ngDoBootstrap(): void {
        this.upgrade.bootstrap(document.body, ['dcApp'], { strictDi: true });

        this.angularTranslationsObserver.languageChange$.subscribe(
            (language: string) => this.localizationService.setLanguage(language)
        );
        this.angularTranslationsObserver.translationsChange$.subscribe(
            (translations: object) => this.setTranslations(translations)
        );
        this.authObserver.accountChange$.subscribe(
            (account: AccountModel) => this.identityService.setAccount(account)
        );
        this.authObserver.tokenChange$.subscribe(
            (token: string) => {
                this.authService.setToken(token);
                let decryptedToken: TokenModel = this.authService.getDecryptedToken();
                this.identityService.setAdmin(Boolean(decryptedToken && decryptedToken.admin));
                this.identityService.setPermissions(decryptedToken.usg);
            }
        );
        this.authObserver.userChange$.subscribe(
            (user: UserProfileModel) => {
                this.identityService.setUser(user);
                this.localizationService.checkLanguageLocale();
            }
        );
    }

    setTranslations(translations: object): void {
        for (const language in translations) {
            if (translations.hasOwnProperty(language)) {
                this.translateService.setTranslation(language, translations[language], true);
            }
        }
    }

}

The admin-routing.module.ts

import {NgModule} from '@angular/core';
import {NgHybridStateDeclaration, UIRouterUpgradeModule} from '@uirouter/angular-hybrid';

const states: NgHybridStateDeclaration[] = [{
    name: 'admin.**',
    url: '/admin',
    loadChildren: () => import('src/app/admin/admin.module')
        .then((result: {AdminModule: any}) => result.AdminModule)
}];

@NgModule({
    imports: [
        UIRouterUpgradeModule.forChild({states: states})
    ],
    exports: [
        UIRouterUpgradeModule
    ],
})
export class AdminRoutingModule {}

And then the admin module

import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MessageCenterModule} from 'src/app/admin/pages/message-center/message-center.module';
import {NewsModule} from 'src/app/admin/pages/news/news.module';
import {SearchModule} from 'src/app/admin/pages/search/search.module';

@NgModule({
    declarations: [],
    imports: [
        CommonModule,
        MessageCenterModule,
        NewsModule,
        SearchModule
    ]
})
export class AdminModule {}

and for example search.module

import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {TranslateModule} from '@ngx-translate/core';
import {ElementsMessagesModule} from 'scripts/modules/elements/messages.a2/messages.module';
import {ElementsNoResultsModule} from 'scripts/modules/elements/no-results.a2/no-results.module';
import {ElementsPageHeaderModule} from 'scripts/modules/elements/page-header/page-header.module';
import {BackendModule} from 'src/app/admin/data/backend/backend.module';
import {ItemModule} from 'src/app/admin/pages/search/item/item.module';
import {SearchRoutingModule} from 'src/app/admin/pages/search/search-routing.module';
import {SearchComponent} from 'src/app/admin/pages/search/search.component';
import {FilterModule} from 'src/app/core/components/filter/filter.module';
import {InputModule} from 'src/app/core/components/filter/input/input.module';
import {PanelModule} from 'src/app/core/components/panel/panel.module';

@NgModule({
    declarations: [SearchComponent],
    imports: [
        BackendModule,
        CommonModule,
        ElementsMessagesModule,
        ElementsNoResultsModule,
        ElementsPageHeaderModule,
        InputModule,
        ItemModule,
        PanelModule,
        SearchRoutingModule,
        TranslateModule,
        FilterModule,
    ],
    exports: [SearchComponent]
})
export class SearchModule { }

with search routing module as you can see not yet lazy loaded, when that will be introduced we would include search-routing module inside the admin module and refer to the search module in the routing module

import {NgModule} from '@angular/core';
import {UIRouterUpgradeModule} from '@uirouter/angular-hybrid';
import {StateDeclaration} from 'hybrid/state.declaration';
import {SearchComponent} from 'src/app/admin/pages/search/search.component';
import {BASIC} from 'src/app/core/auth/permissions/admin.constant';

const states: StateDeclaration[] = [{
    name: 'admin.search',
    url: '/admin/search',
    component: SearchComponent,
    permissions: [BASIC],
    requiresAuth: true
}];

@NgModule({
    imports: [
        UIRouterUpgradeModule.forChild({states: states})
    ],
    exports: [
        UIRouterUpgradeModule
    ],
})
export class SearchRoutingModule {}

Our angularjs module

'use strict';

import angular from 'angular';
// Enable this line and the .run line to enable uiRouter visualizer
// import { visualizer } from '@uirouter/visualizer';

angular.module('dcApp', [
    'dcApp.config', // this needs to be the very first dependency
    'dcApp.publisher.campaigns.modal',

    'dcLayout',
    'dcLibRedirect',
    'dcLibUniqueId',

    /* Pages */
    'dcApp.admin',
    'dcApp.advertiser',
    'dcApp.common',
    'dcApp.leadgeneration',
    'dcApp.publisher'
]);
// Enable this line and the import line to enable uiRouter visualizer
// angular.module('dcApp').run(['$uiRouter', ($uiRouter) => visualizer($uiRouter) ]);

/* Config files */
require('scripts/app-config/app-config.module');
require('scripts/helper/downloadfix');
require('scripts/helper/helper');

/* main module files */
require('scripts/app.controller');
require('hybrid/modal/modal.downgrade');
require('hybrid/cache-service.downgrade');
require('hybrid/modals/campaigns-modal.downgrade');
require('hybrid/modals/invoice-modal.downgrade');
require('hybrid/modals/tickets-modal.downgrade');
require('hybrid/modals/google-modal.downgrade');
require('hybrid/modals/advertiser-last-transactions-modal.downgrade');
require('hybrid/modals/publisher-last-transactions-modal.downgrade');

/* Other main modules */
require('pages/admin/admin.module');
require('pages/advertiser/advertiser.module');
require('pages/common.module');
require('pages/leadgeneration/leadgeneration.module');
require('pages/publisher/publisher.module');
```

and main app.controller
```
'use strict';
import angular               from 'angular';
import $                     from 'jquery';

require('scripts/modules/app-layout/layout.module');

angular.module('dcApp')
    .controller( 'MainController', MainController );

MainController.$inject = [
    '$location',
    '$transitions',
    '$window',
    'AdvertiserFinancialInvoicesInvoiceDetailModal',
    'AdvertiserLastTransactionsModalObserver',
    'AdvertiserTransactionsOverviewDetailModal',
    'AngularModalObserver',
    'AppConfig',
    'AppLayout',
    'AuthAuthenticator',
    'AuthAuthenticatorHelper',
    'AuthIdentity',
    'AuthObserver',
    'CampaignInformationModal',
    'ConnectionsGoogleLoginModal',
    'ElementsMessagesHelper',
    'GoogleModalObserver',
    'InvoiceModalObserver',
    'MediaVerificationModal',
    'PublisherLastTransactionsModalObserver',
    'TicketDetailModal',
    'TicketsModalObserver',
    'TransactionModal'
];

function MainController(
    $location,
    $transitions,
    $window,
    AdvertiserFinancialInvoicesInvoiceDetailModal,
    AdvertiserLastTransactionsModalObserver,
    AdvertiserTransactionsOverviewDetailModal,
    AngularModalObserver,
    AppConfig,
    AppLayout,
    AuthAuthenticator,
    AuthAuthenticatorHelper,
    AuthIdentity,
    AuthObserver,
    CampaignInformationModal,
    ConnectionsGoogleLoginModal,
    ElementsMessagesHelper,
    GoogleModalObserver,
    InvoiceModalObserver,
    MediaVerificationModal,
    PublisherLastTransactionsModalObserver,
    TicketDetailModal,
    TicketsModalObserver,
    TransactionModal
) {

    let $ctrl = this;

    $ctrl.layout = AppLayout;

    $ctrl.$onInit = onInit;

    function onInit() {

        initPage(true);

        $transitions.onError( {}, function( transition ) {
            let transitionError = transition.error();
            if ([4,6].indexOf(transitionError.type) !== -1)
            {
                ElementsMessagesHelper.getInstance('generalError').addMessage( transition.error(), 'error', 'primaryError' );
                AppLayout.hideSplashPage();
                $location.path( '/error' );
            }
        } );

        $transitions.onSuccess({}, function(transition) {
            initPage(transition.from().name !== transition.to().name);
            if ($window.ga) {
                $window.ga('send', 'pageview', { page: $location.url() });
            }
        });

        // No on destroy since the entire app is then gone
        AuthObserver.loginAsChange$.subscribe(function __loginAs(loginAsModel) {
            AuthAuthenticatorHelper.loginAs(
                {
                    id: loginAsModel.account_id,
                    type: loginAsModel.account_type
                },
                loginAsModel.user_id || null,
                loginAsModel.destination || null,
                loginAsModel.sameWindow || null
            );
        });

        AuthObserver.activityChange$.subscribe(AuthAuthenticator.updateLastActivity);
        AuthObserver.logoutExpire$.subscribe(AuthAuthenticator.logoutExpire);
        AuthObserver.updateAccount$.subscribe((account) => AuthIdentity.initAccount(AuthIdentity.getAccountType(), account));

        AngularModalObserver.showMediaVerification$.subscribe((event) => MediaVerificationModal.show(event.mediaId));
        InvoiceModalObserver.openModal$.subscribe(AdvertiserFinancialInvoicesInvoiceDetailModal.show);
        PublisherLastTransactionsModalObserver.openModal$.subscribe((affiliatemarketingId) => TransactionModal.show(affiliatemarketingId));
        AdvertiserLastTransactionsModalObserver.openModal$.subscribe((affiliatemarketingId) => AdvertiserTransactionsOverviewDetailModal.show(affiliatemarketingId));
        TicketsModalObserver.openModal$.subscribe((ticketId) => TicketDetailModal.show(ticketId, false));
        GoogleModalObserver.openModal$.subscribe(() => ConnectionsGoogleLoginModal.show())
    }

    function initPage(pageChange) {
        if (pageChange) {
            $(window).scrollTop(0);
        }

        $ctrl.currentPage = $location.path();
        AppLayout.hideSplashPage();
    }

}
Samantha Adrichem
  • 833
  • 1
  • 12
  • 23
  • So i've changed it to ng build with a minor webpack config for loading our translations. And same error, so I don't think it's inside the webpack config.It must be something really simple and silly. Maybe something new in ivy? – Samantha Adrichem Jun 15 '20 at 09:29
  • FYI, `countries-enum` in package.json is preventing me from running npm install on your demo repository. And I can't run the project because I'm getting a lot of errors like "config\proxy.conf.js does not exist." or "./config/webpack.config.js" does not exist. – Eliezer Berlin Oct 05 '20 at 09:21

3 Answers3

2

After a long search and thanks to the help of two other users, the answer was actually really simple (as expected).

For some strange reason, we're exporting the UIRouterUpgradeModule which should've never been done. (We probably did this because we thought waaay back that thats how it worked? I don't know). But by removing the exports, the error goes away and everything works fine.

So for example that admin routing module becomes:

import {NgModule} from '@angular/core';
import {NgHybridStateDeclaration, UIRouterUpgradeModule} from '@uirouter/angular-hybrid';

const states: NgHybridStateDeclaration[] = [{
    name: 'admin.**',
    url: '/admin',
    loadChildren: () => import('src/app/admin/admin.module')
        .then((result: {AdminModule: any}) => result.AdminModule)
}];

@NgModule({
    imports: [
        UIRouterUpgradeModule.forChild({states: states})
    ]
})
export class AdminRoutingModule {}

Yes there are then some other errors, but those are easily solved. For example in my demo the AdminModule was still imported in the main module and should no longer be imported, since it's lazy loaded.

And each lazy ** state should also exist for example we made admin.**, that means that the AdminModule requires a route named admin. But that is literally said in the error.

Samantha Adrichem
  • 833
  • 1
  • 12
  • 23
1

You should be using UIRouterModule from @uirouter/angular instead of UIRouterUpgradeModule from @uirouter/angular-hybrid if you want to lazily load your angular module. Basically, avoid importing UIRouterUpgradeModule and the mentioned error will go away -

SearchRoutingModule:

const states = [{
    name: 'admin.search',
    url: '/admin/search',
    component: SearchComponent,
    permissions: [],
    requiresAuth: false
}];

@NgModule({
    imports: [
        UIRouterModule.forChild({states: states})
    ],
    exports: [
        UIRouterModule
    ],
})
export class SearchRoutingModule {}

AdminRoutingModule:

const states = [{
    name: 'admin.search.**',
    url: '/admin/search',
    loadChildren: () => import ('./pages/search/search.module').then((module: any) => module.SearchModule)
}];

@NgModule({
    imports: [
        UIRouterModule.forChild({states: states})
    ],
    exports: [
        UIRouterModule
    ],
})
export class AdminRoutingModule {}

AppRoutingModule:

const adminStates = [{
    name: 'admin.**',
    url: '/admin',
    loadChildren: () => import ('./admin/admin.module').then((module: any) => module.AdminModule)
}];

@NgModule({
    imports: [
        UIRouterModule.forRoot({states: adminStates})
    ],
    exports: [
        UIRouterModule
    ],
})
export class AppRoutingModule {}

Note:

There are some other errors that you'll get after above fix which should be easy to fix. Please post separate question for them if you're stuck.

Akash
  • 4,412
  • 4
  • 30
  • 48
  • The original demo app does not use hybrid-module for lazy module. It is used in AppModule only. – Akash Oct 06 '20 at 10:18
  • No, it does use hybrid. I actually found the error though! So i'm going to see if i can split the bounty. It's because we export the UIRouterUpgradeModule.. And I have no clue why we ever did that.. – Samantha Adrichem Oct 06 '20 at 11:38
  • You can't split the bounty, you can give it to two people, But.. Daniel is not eligible for the bounty because his answer was before the bounty was raised. So I gave it to you. – Samantha Adrichem Oct 06 '20 at 11:44
  • Right. There is no way to split the bounty at this point. Hope the answer was helpful. I encountered another error `State already defined` because of the multiple lazy modules in your project. Let me know if you could fix it. – Akash Oct 06 '20 at 11:51
  • 1
    Yeah i fixed that. See my latest push in the public repo. It continued in another error in the admin route needing to exist. Your comment made me try some other stuff and eventually made me find it. – Samantha Adrichem Oct 06 '20 at 15:48
0

Try adding in the scripts section of angular.json this:

"scripts": [
    "./.node_modules/angular/angular.js"
]

Or, try adding this in your main.ts (this is the one I use):

import {setAngularJSGlobal} from '@angular/upgrade/static';
import * as angular from 'angular';
setAngularJSGlobal(angular);
Daniel
  • 21,933
  • 14
  • 72
  • 101
  • The setAngularJSGlobal is already in our app.module. I’ve tried moving it to the main ts, but that didn’t work. Will try the angular.json version monday – Samantha Adrichem Aug 09 '20 at 04:17
  • I would put `setAngularJSGlobal` in `main.ts` instead of the `app.module.ts` to ensure it's available from the get go. I've put together an example of using UI-Rouyter in a hybrid application, check it out here: https://github.com/dwilches/Angular-Hybrid-1 – Daniel Aug 09 '20 at 17:08
  • The angular.json fix doesn't work either. I don't mind having it in the main,ts, or app.module, but it doesn't work in either version. Will take a look at your demo. :) – Samantha Adrichem Aug 10 '20 at 07:22
  • As far as I can see. Your demo repository doesn't use loadChildren, which is where the problem starts :(. I've contacted you privately, sorry if you did not want me to. Just ignore me then, with a demo repository. (Since I don't want to share it everywhere) – Samantha Adrichem Aug 10 '20 at 08:47
  • Hello. I gave it a look but I'm not familiar with UIRouter for Angular and how it handles lazy loading. Something I noticed is when your code is not invoking "bootstrap" again when it loads the lazy modules (check [this](https://angular.io/guide/upgrade#create-a-service-to-lazy-load-angularjs)). In that page they say to invoke "app.bootstrap" but I had to do "upgrade.bootstrap" to make my project run. Hope this helps. – Daniel Aug 11 '20 at 05:16