I am trying to do something here, but not sure if it can be done. I want to create a model class like this:
import { Inject } from '@angular/core';
import {
Element,
Image,
} from '@situlive/situ-angular-components/contentful';
export class ImageColumn {
title: string;
backgroundImage: Image;
backgroundImageAlignment: string;
constructor(
element: Element
) {
this.title = element.fields.title;
this.backgroundImageAlignment = element.fields.backgroundImageAlignment;
}
}
This is so that in a component or service I can just do a new ImageColumn(element)
and it will bind the properties for me.
Easy so far.
Now I have a complication :) I need to bind the the backgroundImage, which is done through a service. I updated the constructor to this:
import { Inject } from '@angular/core';
import {
ContentfulService,
Element,
Image,
} from '@situlive/situ-angular-components/contentful';
export class ImageColumn {
title: string;
backgroundImage: Image;
backgroundImageAlignment: string;
constructor(
contentfulService: ContentfulService,
element: Element
) {
this.title = element.fields.title;
this.backgroundImageAlignment = element.fields.backgroundImageAlignment;
this.backgroundImage = this.contentfulService.createImage(
element.fields.backgroundImage[0]
);
}
}
which is fine, but it causes an issue, because now anywhere where I use an ImageColumn I now have to pass in the contentfulService. I would really love to be able to pass the service without needing to supply it in the constructor.
I have done this before with services using injection tokens, so I figured I could do it here. I created an injection token like this:
import { InjectionToken } from '@angular/core';
import { ContentfulService } from '@situlive/situ-angular-components/contentful';
export const CONTENTFUL_SERVICE = new InjectionToken<ContentfulService>(
'CONTENTFUL_SERVICE'
);
which I provided in my module like this:
@NgModule({
imports: [
CommonModule,
HttpClientModule,
RouterModule,
AuthModule.forRoot(environment.auth0),
ContentfulModule.forRoot(environment.contentful),
],
declarations: [FooterComponent, HeaderComponent],
exports: [FooterComponent, HeaderComponent],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: BearerInterceptor,
multi: true,
},
{
provide: CONTENTFUL_SERVICE,
useClass: ContentfulService,
multi: true,
},
],
})
export class CoreModule {}
So I figured I would be able to do this to my model:
import { Inject } from '@angular/core';
import {
ContentfulService,
Element,
Image,
} from '@situlive/situ-angular-components/contentful';
import { CONTENTFUL_SERVICE } from '../contentful-service.token';
export class ImageColumn {
title: string;
backgroundImage: Image;
backgroundImageAlignment: string;
constructor(
@Inject(CONTENTFUL_SERVICE) private contentfulService: ContentfulService,
element: Element
) {
this.title = element.fields.title;
this.backgroundImageAlignment = element.fields.backgroundImageAlignment;
this.backgroundImage = this.contentfulService.createImage(
element.fields.backgroundImage[0]
);
}
}
The problem is, now when i do a new ImageColumn(element)
it complains that I need 2 arguments but only got 1.
Does anyone know how I can get around this?
I think it doesn't work that way because you didn't declare any provider for the
ImageColumn
. Declaring the provider would let the injector know how to obtain dependencies when you inject theImageColumn
as follows:but since you want to instantiate it manually, I'm not sure you can let Angular know how to automatically resolve the injection token.
What I think you can do instead is to provide the
Injector
when you instantiateImageColumn
.foo.component.ts
and then in your
ImageColumn
's constructor you can inject anything that has a provider declared, including that service: