in Angular 12 I have a simplified component like that:
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.less']
})
export class ListComponent implements OnInit {
@Input() dataType: string;
items: Item[] = [];
constructor(private ds: DataStorageService) { }
ngOnInit(): void {
this.items = this.ds.fetchAll();
}
and my simplified DataStorageService looks like this:
@Injectable({providedIn: 'root'})
export class DataStorageService {
private readonly dataType: string;
private readonly apiEndpoint: string;
constructor(dataType: string, private http: HttpClient) {
this.dataType = dataType;
this.apiEndpoint = environment.config.urlLogin '/api/' this.dataType;
}
fetchAll(string) {
return this.http.get(this.apiEndpoint) as Observable<Item[]>;
}
I want to use
<app-list data-type="products">
and using products as a value in my DataStorageService - without passing it in every function which might make us of it.
I tried injecting it with useValue and was thinking about using a ServiceFactory - but I am stuck and don't know how to continue from here.
Especially since Item is my generic Type for which I have interface extensions again based on dataType string, e.g. Product extends Item for dataType products.
CodePudding user response:
Your service factory can look something like this:
@Injectable(providedIn: 'root')
export class DataServiceFactory {
constructor(private http: HttpClient) {}
getDataService(dataType: string): DataStorageService {
return new DataStorageService(dataType, this.http);
}
}
Then your list component could look like this:
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.less']
})
export class ListComponent implements OnInit {
@Input() dataType: string;
items: Item[] = [];
private dataService: DataStorageService;
constructor(private serviceFactory: DataServiceFactory) { }
ngOnInit(): void {
this.dataService = this.serviceFactory.getDataService(this.dataType);
this.dataService.fetchAll().subscribe(items => this.items = items);
}
}
Your DataStorageService
does not even need the Injectable
decorator at this point, as it will be manually instantiated. You don't rely on the injector to provide it for you.