Skip to content

@inject

ts
inject<T>(key: ContextKey<T>): ValueObserver<T | undefined>

Field sugar over $inject(). It asks once, at construction.

Usage

ts
@
component
({
name
: 'Output' })
class
Output
extends
Base
{
@
inject
(
CountContext
)
count
?:
Signal
<number>;
mounted
() {
// The request may not have been answered yet. return this.
count
?.
subscribe
((
value
) => {
this.
$el
.
textContent
=
String
(
value
);
}); } }

The field type includes undefined, because the request is asynchronous and the value lands when a provider answers.

When to use it, and when not

SituationReach for
the value is there for the whole life of the instance@inject
the consumer must be able to wait through several mount cycles$inject() from mounted()
the answer is optional and there is a fallback$injectSync()
the provider comes and goessubscribeContext()

@inject asks once, at construction. $inject() from mounted() is unmount-scoped: $unmount() cancels the pending request, and a new mount asks again. That difference is the whole reason both exist.

A plain field or an accessor

ts
@
component
({
name
: 'Output' })
class
Output
extends
Base
{
@
inject
(
CountContext
)
a
?:
Signal
<number>;
@
inject
(
CountContext
) accessor
b
:
Signal
<number> | undefined;
}

The function form

ts
class 
Output
extends
Base
{
static
config
= {
name
: 'Output' };
async
mounted
() {
const
count
= await this.
$inject
(
CountContext
);
return
count
.
subscribe
((
value
) => {
this.
$el
.
textContent
=
String
(
value
);
}); } }

The await form has no undefined to handle, which is usually the better trade.

MIT Licensed