Can factory provider have optional dependencies?
For example:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]
}
})
class MyModule {}
Can useFactory have optional dependencies?
angular typescript dependency-injection
add a comment |
For example:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]
}
})
class MyModule {}
Can useFactory have optional dependencies?
angular typescript dependency-injection
add a comment |
For example:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]
}
})
class MyModule {}
Can useFactory have optional dependencies?
angular typescript dependency-injection
For example:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [SOME_DEP]
}
})
class MyModule {}
Can useFactory have optional dependencies?
angular typescript dependency-injection
angular typescript dependency-injection
asked Sep 1 '16 at 18:54
Krzysztof Bogdan
456213
456213
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
According to official doc, you can do the following:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
See https://angular.io/api/core/FactoryProvider#example for more
add a comment |
I have found such a workaround:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
add a comment |
Factory accepts a function.
Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.
In other words, currently you can only decorate a class and class members.
parameter refers to the parameter of a method, not a function.
So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.
This a language/spec limitation that might change in the future.
Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.
According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.
It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!
add a comment |
It is indeed possible to declare an optional dependency for a factory provider.
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
Then, in your providers list, provide the default using a value provider
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
The service will use the provided default value of the parameter (which could be undefined
), unless the consumer overrides the value later in the list of providers.
The HttpModule
from @angular/http
uses this pattern to provide the optional dependency RequestOptions
to its services.
add a comment |
so I've been trying to solve it. Check this:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39278930%2fcan-factory-provider-have-optional-dependencies%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
According to official doc, you can do the following:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
See https://angular.io/api/core/FactoryProvider#example for more
add a comment |
According to official doc, you can do the following:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
See https://angular.io/api/core/FactoryProvider#example for more
add a comment |
According to official doc, you can do the following:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
See https://angular.io/api/core/FactoryProvider#example for more
According to official doc, you can do the following:
const Location = new InjectionToken('location');
const Hash = new InjectionToken('hash');
const injector = Injector.create([{
provide: Hash,
useFactory: (location: string) => `Hash for: ${location}`,
// use a nested array to define metadata for dependencies.
deps: [[new Optional(), Location]]
}]);
expect(injector.get(Hash)).toEqual('Hash for: null');
See https://angular.io/api/core/FactoryProvider#example for more
answered Feb 1 at 16:38
maxime1992
10.5k43473
10.5k43473
add a comment |
add a comment |
I have found such a workaround:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
add a comment |
I have found such a workaround:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
add a comment |
I have found such a workaround:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
I have found such a workaround:
class OptionalDepHolder {
constructor(@Optional() @Inject(SOME_DEP) public optionalDep) {}
}
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (holder) => new MyService(holder.optionalDep)
deps: [OptionalDepHolder]
}
})
class MyModule {}
answered Sep 1 '16 at 21:41
Krzysztof Bogdan
456213
456213
add a comment |
add a comment |
Factory accepts a function.
Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.
In other words, currently you can only decorate a class and class members.
parameter refers to the parameter of a method, not a function.
So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.
This a language/spec limitation that might change in the future.
Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.
According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.
It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!
add a comment |
Factory accepts a function.
Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.
In other words, currently you can only decorate a class and class members.
parameter refers to the parameter of a method, not a function.
So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.
This a language/spec limitation that might change in the future.
Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.
According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.
It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!
add a comment |
Factory accepts a function.
Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.
In other words, currently you can only decorate a class and class members.
parameter refers to the parameter of a method, not a function.
So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.
This a language/spec limitation that might change in the future.
Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.
According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.
It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!
Factory accepts a function.
Decorators in typescript can apply on: class declaration, method, accessor, property, or parameter.
In other words, currently you can only decorate a class and class members.
parameter refers to the parameter of a method, not a function.
So, since you can't decorate function and more so parameters in a function you can't set the @Optional tag.
This a language/spec limitation that might change in the future.
Another thing to note is that the metadata feature supported by typescript and consumed by angular using reflect-metadata is designed to work on classes. This is of course nonsense, classes are functions... but this is the general mental model.
According to the documentation, the deps array accepts provider tokens which means you can't hint about a dependency being optional.
It is a good idea to have support for optional dependencies in factories. You should open a GH issue with a feature request!
answered Sep 1 '16 at 20:59
Shlomi Assaf
1,272813
1,272813
add a comment |
add a comment |
It is indeed possible to declare an optional dependency for a factory provider.
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
Then, in your providers list, provide the default using a value provider
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
The service will use the provided default value of the parameter (which could be undefined
), unless the consumer overrides the value later in the list of providers.
The HttpModule
from @angular/http
uses this pattern to provide the optional dependency RequestOptions
to its services.
add a comment |
It is indeed possible to declare an optional dependency for a factory provider.
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
Then, in your providers list, provide the default using a value provider
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
The service will use the provided default value of the parameter (which could be undefined
), unless the consumer overrides the value later in the list of providers.
The HttpModule
from @angular/http
uses this pattern to provide the optional dependency RequestOptions
to its services.
add a comment |
It is indeed possible to declare an optional dependency for a factory provider.
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
Then, in your providers list, provide the default using a value provider
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
The service will use the provided default value of the parameter (which could be undefined
), unless the consumer overrides the value later in the list of providers.
The HttpModule
from @angular/http
uses this pattern to provide the optional dependency RequestOptions
to its services.
It is indeed possible to declare an optional dependency for a factory provider.
export const MY_OPTIONAL_SERVICE_PARAMETER = new OpaqueToken('my_optional_service_parameter');
export const myOptionalServiceParameterDefault = 42;
Then, in your providers list, provide the default using a value provider
@NgModule({
providers: [
{
provide: MY_OPTIONAL_SERVICE_PARAMETER,
useValue: myOptionalServiceParameterDefault
},
{
provide: MyService,
useFactory: (optionalParam) => new MyService(optionalParam)
deps: [MY_OPTIONAL_SERVICE_PARAMETER]
}
})
export class Module {}
The service will use the provided default value of the parameter (which could be undefined
), unless the consumer overrides the value later in the list of providers.
The HttpModule
from @angular/http
uses this pattern to provide the optional dependency RequestOptions
to its services.
edited Nov 18 '16 at 12:07
answered Nov 17 '16 at 23:55
ovangle
5641620
5641620
add a comment |
add a comment |
so I've been trying to solve it. Check this:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
add a comment |
so I've been trying to solve it. Check this:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
add a comment |
so I've been trying to solve it. Check this:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
so I've been trying to solve it. Check this:
@NgModule ({
providers: [
{ provide: MyService,
useFactory: (optionalDep) => new MyService(optionalDep)
deps: [[new Optional(), new Inject(SOME_DEP)]]
}
})
class MyModule {}
answered Nov 11 at 17:25
Jan Kremeň
1
1
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39278930%2fcan-factory-provider-have-optional-dependencies%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown