Angular downgradeComponent not being created
Asked Answered
M

2

1

I have just setup a hybrid AngularJS / Angular 5 application with downgradeModule. I have converted a very small component from AngularJS to Angular but it is never being created. I have put console.logs throughout the component to see if certain bits are called and others not. The file is loaded but the component never is.

I have read what feels like hundreds of tutorials but I must be missing something.

Note that I got this far in converting the component, realised it was not being created, then stopped porting the rest. Hence why driverImage is not currently on the converted component.

Here is a stackblitz with a test component that shows it not working https://angularjs-q1vrpe.stackblitz.io/

Bootstrap

import * as angular from "angular";

import { downgradeModule } from "@angular/upgrade/static";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { StaticProvider } from "@angular/core";

import { MainAngularModule } from "./app.module";
import "./index.module";

const bootstrapFn = (extraProviders: StaticProvider[]) => {
    console.log("1"); <--- never output!
    const platformRef = platformBrowserDynamic(extraProviders);
    return platformRef.bootstrapModule(MainAngularModule);
};

const downgradedModule = downgradeModule(bootstrapFn);

angular.module('angularJsModule', ['myApp', downgradedModule]);

angular.bootstrap(document, ['angularJsModule']);

App.Module (MainAngularModule)

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';

@NgModule({
    imports: [
        BrowserModule,
        UpgradeModule
    ],
    declarations: [Ng2TestComponent, DriverImageComponent],
    entryComponents: [Ng2TestComponent, DriverImageComponent]
})

export class MainAngularModule {
    // Empty placeholder method to satisfy the `Compiler`.
    ngDoBootstrap() { }
}

index.module (Stripped most of the dependencies out for brevity)

angular
    .module("myApp", [
        "constants",
        "ngMaterial",
        "ngSanitize", ... ]);

The newly converted Component:

import { Component, Input, OnInit, OnChanges } from '@angular/core';
import { IDriver } from "../interfaces/IDriver";

console.log("here"); // --> This is hit

@Component({
    selector: "driver-image",
    template: `<div class="driver-image" ng-style="{'background-image' : 'url('+$ctrl.driverImage+')'}"></div>`
})

export class DriverImageComponent implements OnInit, OnChanges {
    @Input() driver: IDriver;
    @Input() small: boolean;

    constructor() {
        console.log("1"); // --- Not hit
    }

    ngOnInit() {
        console.log("ONINITNINTT"); // --> Not hit
    }

    ngOnChanges() { }
}

The related modules.ts

import { downgradeComponent } from "@angular/upgrade/static";
...
.component("driverImage", downgradeComponent({ component: DriverImageComponent }))
Maintenance answered 24/9, 2018 at 15:44 Comment(0)
M
3

The answer is actually really simple, it just took me forever to see it.

Contrary to what you might believe, you need to change your AngularJS component to be registered as a directive, NOT, a component.

Maintenance answered 29/10, 2018 at 16:18 Comment(0)
T
1

without a Stackblitz this is pretty hard to reproduce (btw do you have any errors in the console?). I just write down some suggestions that you can try. If you tell me what worked, I'll update my answer

instead of import { platformBrowser } from "@angular/platform-browser"; use this one instead import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; (can't quite tell you the difference but platform-browser does not work in my projects)

Ok while writing this I think I found the answer. Your problem is you are not loading the component that should be downgraded in your Angular 5 application - everything you want to downgrade still needs to be properly loaded in Angular 5 itself. So try adding a entryComponents: [DriverImageComponent] to your App.Module

Edit:

Ok based on your comment it looks like your Application is not even bootstrapped. Are you sure you are using your component on the page that you are currently using? If the component is not being used, it will not be loaded and Angular won't be bootstrapped.

There are certain scenarios where you need to force this bootstrapping in the beginning.

Create an Bootstrap component

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

@Component({
    selector: 'my-bootstrap',
    template: '',
})
export class BootstrapComponent {}

Add it to your App.Module

declarations: [
    BootstrapComponent,
],
entryComponents: [
    BootstrapComponent,
],

Force it to be loaded in your main index.html by adding <my-bootstrap></my-bootstrap in the beginning of the <body>

Transformation answered 25/9, 2018 at 9:8 Comment(4)
Hi. Thanks for answering! I have changed to platformBrowserDynamic and added entryComponents.. None seem to work. Interestingly If I put console logs in my MainAngularModule or the bootstrapFn none seem to get executed... I wonder if this is the root cause? Also I have no errors in console.Maintenance
ok it looks like your Angular 5 is not even bootstrapped. updated my answer with another suggestion :)Transformation
Nicolas thanks so much for your help but I still cannot get it working.. I have created a stackblitz with all your recent suggestions.. angularjs-q1vrpe.stackblitz.ioMaintenance
hi chris, i'm also stucked... don't know what I'm missing :D ported your example to Angular 6 and removed all unneeded things. stackblitz.com/edit/angular-ssxhj2?file=src%2Fmain.ts Feel free to include this in your question or have a look :D curious for the solution now^^Transformation

© 2022 - 2024 — McMap. All rights reserved.