Skip to content

aot - platform specific files angular dependency injection bug #1334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bzaruk opened this issue May 19, 2018 · 6 comments
Closed

aot - platform specific files angular dependency injection bug #1334

bzaruk opened this issue May 19, 2018 · 6 comments

Comments

@bzaruk
Copy link

bzaruk commented May 19, 2018

Hi,

I searched some for this issue I have and the only thing I found is this, but this actually didn't help cause I already implements the solution there by @sis0k0

The issue is that when I run the project with --env.aot flag something happened to the dependency injection of the platform specific files, and I will give an example:

I created a ModalDialogHelper for every modal dialog I have to simplify the creation of the dialog, because there is some cases that I want to have a different UI dialog for every specific platform I separate it to different platform specific files, so it looks kind of like this:

itemsListWithIconsModalDialogHelper.d.ts:

import { ViewContainerRef } from "@angular/core";

declare class ItemsListWithIconsModalDialogHelper {
    public createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }>;
}

itemsListWithIconsModalDialogHelper.android.ts:

import { Injectable, ViewContainerRef } from '@angular/core';
import { ItemsListWithIconsModalDialogComponent } from "./itemsListWithIconsModalDialog.component";
import { ModalDialogService, ModalDialogOptions } from "nativescript-angular/modal-dialog";

@Injectable()
export class ItemsListWithIconsModalDialogHelper {
    constructor(private _modalService: ModalDialogService) { }

    public createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }> {
        let options: ModalDialogOptions = {
            viewContainerRef: params.vcRef,
            context: {
                title: params.title,
                actionsData: params.actionsData
            },
            fullscreen: false
        };
        return this._modalService.showModal(ItemsListWithIconsModalDialogComponent, options);
    }
}

itemsListWithIconsModalDialogHelper.ios.ts:

import { Injectable, ViewContainerRef } from '@angular/core';
import * as dialogs from "ui/dialogs";

@Injectable()
export class ItemsListWithIconsModalDialogHelper {
    constructor() { }

    public createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }> {
        const cancelText = "Cancel";
        return dialogs.action({
            message: params.title || undefined,
            cancelButtonText: cancelText,
            actions: params.actionsData.map(actionData => {
                return actionData.text;
            })
        }).then(result => {
            if(result == cancelText) {
                return undefined;
            }
            return { pickedIndex: params.actionsData.indexOf(params.actionsData.find(actionData => { return actionData.text == result; })) };
        });
    }
}

The actual thing that matter in this sample is the line return this._modalService.showModal... in the itemsListWithIconsModalDialogHelper.android.ts file, because there you can see that the this._modalService is undefined, something with the dependency injection I guess...

this issue doesn't happens if I run it only with --bundle flag.

The example show you that this is problem in the android specific file but it happens also in the ios specific file.

Thank you! :)

@bzaruk
Copy link
Author

bzaruk commented May 21, 2018

here is an project example - https://play.nativescript.org/?template=play-ng&id=Gih9oD

Be sure to Download the project and run it with --env.aot flag

@hosikiti
Copy link

hosikiti commented May 29, 2018

@shabib3 I faced the same problem before. For now , it seems platform specific files with .android or .ios are only supported for @Component on Webpack build.

For @Injectable , @Directive, @Pipe, try following:

First, create typescript definition file, say, itemsListWithIconsModalDialogHelperLogic.d.ts.
Put any interface methods you would like to call. (in your case , createItemsListWithIconsModalDialog() )

export class ItemsListWithIconsModalDialogHelperLogic {
  static createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }>;
}

Then, separete your platform specific logic from @Injectable file into two files, for instance,
itemsListWithIconsModalDialogHelperLogic.android.ts and itemsListWithIconsModalDialogHelperLogic.ios.ts. Here, you need to implement methods that you defined in the itemsListWithIconsModalDialogHelperLogic.d.ts.

export class ItemsListWithIconsModalDialogHelperLogic {
   static createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }>{
      // any platform specific implementation.
  }
}

Finally, import the logic class from one itemsListWithIconsModalDialogHelper.ts in which you will have @Injectable.

import { Injectable, ViewContainerRef } from '@angular/core';
import { ItemsListWithIconsModalDialogComponent } from "./itemsListWithIconsModalDialog.component";
import { ModalDialogService, ModalDialogOptions } from "nativescript-angular/modal-dialog";
import { ItemsListWithIconsModalDialogHelperLogic } from "./itemsListWithIconsModalDialogHelperLogic"; // added

@Injectable()
export class ItemsListWithIconsModalDialogHelper {
    constructor(private _modalService: ModalDialogService) { }

    public createItemsListWithIconsModalDialog(params: { title: string, actionsData: Array<{ iconStringValue: string, text: string, color: string }>, vcRef: ViewContainerRef }): Promise<{ pickedIndex: number }> {
        return ItemsListWithIconsModalDialogHelperLogic.createItemsListWithIconsModalDialog( params, vcRef );
    }
}

Folder structure:

itemsListWithIconsModalDialogHelperLogic.d.ts
itemsListWithIconsModalDialogHelperLogic.android.ts
itemsListWithIconsModalDialogHelperLogic.ios.ts
itemsListWithIconsModalDialogHelper.ts

Thanks.

@bzaruk
Copy link
Author

bzaruk commented May 29, 2018

@hosikiti - Thank you for the long suggestion!
From what I get from you the only thing I need to change is to change the 'declare' to 'export' in 'itemsListWithIconsModalDialogHelperLogic.d.ts'.

I tried it and I get the same error...any idea?

@hosikiti
Copy link

@shabib3 You're welcome. Problem is you have two @Injectable classes. Instead, you need to have only one file in which @Injectable is declared.

@bzaruk
Copy link
Author

bzaruk commented May 29, 2018

Ohhh! Gotcha!!

Awesome workaround! didn't think about it :)

Thanks you!

@bzaruk
Copy link
Author

bzaruk commented May 29, 2018

btw, I got to pass the _modalService as parameter to the ItemsListWithIconsModalDialogHelperLogic.createItemsListWithIconsModalDialog function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants