Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ivy is not liking the @Host() decorator #31539

Closed
p3x-robot opened this issue Jul 13, 2019 · 7 comments

Comments

@p3x-robot
Copy link

commented Jul 13, 2019

馃悶 bug report

Affected Package

The issue is caused by package @angular/....

@Host() decorator is not working with Ivy.

Description

A clear and concise description of the problem...

I was using this (now I have to use a global variable to get this host as Ivy is not liking it):

馃敩 Minimal Reproduction

import {Layout} from '../layout/cory-layout';

 constructor(
        @Host() public parent: Layout,
        public sanitize: DomSanitizer,
        protected locale: LocaleService,
    )

馃敟 Exception or Error


core.js:7383 ERROR Error: NodeInjector: NOT_FOUND [cory_layout_Layout]
    at getOrCreateInjectable (core.js:7166)
    at Object.傻傻directiveInject (core.js:14735)
    at NodeInjectorFactory.factory (cory-page.ts:44)
    at getNodeInjectable (core.js:7261)
    at core.js:11972
    at createRootComponent (core.js:18137)
    at ComponentFactory.create (core.js:22946)
    at ViewContainerRef_.createComponent (core.js:19384)
    at RouterOutlet.activateWith (router.js:5194)
    at RouterOutlet.ngOnInit (router.js:5116)

馃實 Your Environment

Angular Version:

8.1.0

image

@ngbot ngbot bot added this to the needsTriage milestone Jul 13, 2019

@JoostK

This comment has been minimized.

Copy link
Member

commented Jul 14, 2019

Hi @p3x-robot,

I suspect you are experiencing the following known breaking change:

If a token is injected with the @Host or @Self flag, the module injector is not searched for that token (previously, tokens marked with these flags would still search at the module level).

Strictly speaking, this is actually a bug fix compared to ViewEngine (VE). The reason is that in VE, the @Host restrictions are fully applied during compilation鈥not runtime鈥攁s part of compiling the element that hosts the component.

Looking at your stacktrace, it looks like the component is dynamically created and inserted by the router. Therefore, no element exists that statically hosts your component, so the VE compiler did never actually apply the @Host restriction during compilation, so the @Host decorator is effectively ignored as no runtime checking is being performed in VE.

The situation has changed with Ivy, as Ivy does in fact verify the @Host restriction during runtime. Therefore, even for dynamically inserted components the @Host decorator is verified.

Note that for the above explanation to make sense, it is relevant to know that the injector used to dynamically create a component is considered a module injector, not an element injector, even if the injector does correspond with an element injector.

@p3x-robot

This comment has been minimized.

Copy link
Author

commented Jul 14, 2019

ciao!
so, is have to use @HostBinding instead of @Host or just simply is not working now, right?
Because not a big issue, as I put into a global variable and I can use the variables from there, just it was strange why it was not working...

@p3x-robot

This comment has been minimized.

Copy link
Author

commented Jul 14, 2019

what do you mean dynamically inserted components? i am using Ivy with AOT, it is not dynamic.

@JoostK

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

What I meant by dynamically inserted components is components that are instantiated by the router, in this case. So yes, the component itself can be AOT compiled, however this compiled component can be dynamically inserted during runtime using APIs such as ViewContainerRef and ComponentFactory. This is exactly what the router does: based on the current URL and your app's route table, it will figure out the corresponding component type and create an instance of it and insert it at <router-outlet>.

To understand the @Host decorator better, I'd recommend these articles:

Bottom line is that @Host and @HostBinding are quite different. The former is used for Angular's DI system, whereas the latter can be used to bind values in Angular directives. I'm not sure what you're trying to achieve, as I don't see what you mean by using a global variable to work around the problem.

@p3x-robot

This comment has been minimized.

Copy link
Author

commented Jul 15, 2019

@JoostK

This comment has been minimized.

Copy link
Member

commented Jul 15, 2019

Why not just drop the @Host decorator? It will bring you in the same situation as was the case without Ivy.

@p3x-robot

This comment has been minimized.

Copy link
Author

commented Jul 15, 2019

wow, it works, without decorator, thanks so much!
more Angular way.... I love this Ivy...

@p3x-robot p3x-robot closed this Jul 15, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can鈥檛 perform that action at this time.