* Returns the value associated to the given token from the node injector. * * @param tNode The Node where the search for the injector should start * @param lView The `LView` that contains the `tNode` * @param token The token to look for * @param flags Injection flags * @param notFoundValue The
( tNode: TDirectiveHostNode, lView: LView, token: ProviderToken<T>, flags: InternalInjectFlags, notFoundValue?: any, )
| 504 | * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided |
| 505 | */ |
| 506 | function lookupTokenUsingNodeInjector<T>( |
| 507 | tNode: TDirectiveHostNode, |
| 508 | lView: LView, |
| 509 | token: ProviderToken<T>, |
| 510 | flags: InternalInjectFlags, |
| 511 | notFoundValue?: any, |
| 512 | ) { |
| 513 | const bloomHash = bloomHashBitOrFactory(token); |
| 514 | // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef |
| 515 | // so just call the factory function to create it. |
| 516 | if (typeof bloomHash === 'function') { |
| 517 | if (!enterDI(lView, tNode, flags)) { |
| 518 | // Failed to enter DI, try module injector instead. If a token is injected with the @Host |
| 519 | // flag, the module injector is not searched for that token in Ivy. |
| 520 | return flags & InternalInjectFlags.Host |
| 521 | ? notFoundValueOrThrow<T>(notFoundValue, token, flags) |
| 522 | : lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue); |
| 523 | } |
| 524 | try { |
| 525 | let value: unknown; |
| 526 | |
| 527 | if (ngDevMode) { |
| 528 | runInInjectorProfilerContext( |
| 529 | new NodeInjector(getCurrentTNode() as TElementNode, getLView()), |
| 530 | token as Type<T>, |
| 531 | () => { |
| 532 | emitInjectorToCreateInstanceEvent(token); |
| 533 | value = bloomHash(flags); |
| 534 | emitInstanceCreatedByInjectorEvent(value); |
| 535 | }, |
| 536 | ); |
| 537 | } else { |
| 538 | value = bloomHash(flags); |
| 539 | } |
| 540 | |
| 541 | if (value == null && !(flags & InternalInjectFlags.Optional)) { |
| 542 | throwProviderNotFoundError(token); |
| 543 | } else { |
| 544 | return value; |
| 545 | } |
| 546 | } finally { |
| 547 | leaveDI(); |
| 548 | } |
| 549 | } else if (typeof bloomHash === 'number') { |
| 550 | // A reference to the previous injector TView that was found while climbing the element |
| 551 | // injector tree. This is used to know if viewProviders can be accessed on the current |
| 552 | // injector. |
| 553 | let previousTView: TView | null = null; |
| 554 | let injectorIndex = getInjectorIndex(tNode, lView); |
| 555 | let parentLocation = NO_PARENT_INJECTOR; |
| 556 | let hostTElementNode: TNode | null = |
| 557 | flags & InternalInjectFlags.Host ? lView[DECLARATION_COMPONENT_VIEW][T_HOST] : null; |
| 558 | |
| 559 | // If we should skip this injector, or if there is no injector on this node, start by |
| 560 | // searching the parent injector. |
| 561 | if (injectorIndex === -1 || flags & InternalInjectFlags.SkipSelf) { |
| 562 | parentLocation = |
| 563 | injectorIndex === -1 |
no test coverage detected
searching dependent graphs…