Should we utilize the component @Input as a parameter for the injected service constructor, or should we opt for the ServiceFactory

Within Angular 12 lies a simplified component structured as follows:

@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();
  }

The simplified version of my DataStorageService is outlined below:

@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 aim to utilize

<app-list data-type="products">

And incorporate products as a value within my DataStorageService - without the need to pass it in every function that relies on it.

I have attempted to inject it using useValue, and the notion of utilizing a ServiceFactory has crossed my mind - but I find myself at an impasse and uncertain on how to proceed further.

This is especially challenging since Item serves as my generic Type with interface extensions centered around the dataType string, such as Product extends Item for the products dataType.

Answer №1

Here is an example of how your service factory can be structured:

@Injectable(providedIn: 'root')
export class DataServiceFactory {
  constructor(private http: HttpClient) {}
  
  getDataService(dataType: string): DataStorageService {
    return new DataStorageService(dataType, this.http);
  }
}

Next, let's take a look at how your list component can be implemented:

@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);
  }
}

It's worth noting that your DataStorageService doesn't require the Injectable decorator in this context since it will be instantiated manually. You're not relying on the injector to provide it for you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the most effective way to handle DOM events in Angular 8?

Looking to listen for the 'storage' event from the window in Angular 8. What is the recommended approach to achieving this in Angular? window.addEventListener('storage', () => { }); One method involves using Renderer2, but are ther ...

Different ESLint configurations for mjs, js, and ts files

For my project, I've set up ESM (.mjs) files for server-side code, CommonJS (.js) for tooling, and TypeScript (.ts) for the client side. In VS Code, when I look at CommonJS files, I'm getting errors related to requires such as "Require statement ...

Callback after completion of a for loop in Angular TypeScript

During the execution of my javascript async function, I encountered a situation where my printing code was running before the div creation. I needed to ensure that my print code would run only after the completion of the for loop, but I struggled to find a ...

When there is only one value, the BehaviorSubject can be hit multiple times

Recently, I implemented BehaviourSubject in a shared service to retrieve the current value when clicking a button. Everything seems to be working fine, however, there are instances where the API call within the subscribe block of BehaviourSubject is being ...

Making sure the checkbox stays selected in an angular environment

After experimenting with Angular 9 and a custom input, I achieved the following result => https://stackblitz.com/edit/angular-ivy-rgsatp My goal was to prevent users from disabling a radio button that is currently checked. Therefore, I made changes in ...

Comparing Angular's 'ng serve' and 'npm start' commands

Just a quick query regarding angular-cli. I'm curious, is it correct that when I use ng serve, I am utilizing the global installation of angular-cli but when I opt for npm start, I am using the local one? ...

Unlock the encrypted information in the blockchain

I've been working on encrypting and decrypting values using Node's built-in crypto module. I found a helpful tutorial that showed me how to encrypt the data, but it didn't provide any sample code for decryption. When I tried using code from ...

Is there a way for me to reach the ngFor variable within a different ngFor loop?

Here is an example code snippet to display user details. Currently, we have only one user and three permissions in an array: 1) Users = [{'FirstName':'John','permission':['masters','transactions']}] 2) p ...

What are the advantages of combining the website URL and API URL within the Angular service?

When deploying my application in a production environment, I encounter an issue with the URL addresses. The web address is , while the API address is . However, when making a request to the API through Angular, the URLs get concatenated into . This issue d ...

Error: The class constructor [] must be called with the 'new' keyword when creating instances in a Vite project

I encountered an issue in my small Vue 3 project set up with Vite where I received the error message Class constructor XX cannot be invoked without 'new'. After researching online, it seems that this problem typically arises when a transpiled cla ...

When using Ionic 3 on an Android device, the keyboard is causing the tabs and app content to shift upwards

I'm currently working on an Ionic 3 app and encountering a problem. Whenever I click on the search function, the keyboard opens and pushes all the content of the app to the top. https://i.sstatic.net/GaPW8.png https://i.sstatic.net/7d6Fm.png Here i ...

Create an object using a combination of different promises

Creating an object from multiple promise results can be done in a few different ways. One common method is using Promise.all like so: const allPromises = await Promise.all(asyncResult1, asyncResult2); allPromises.then([result1, result2] => { return { ...

Developing custom events in an NPM package

Developing a basic npm package with signalr integration has been my recent project. Here's how it works: First, the user installs the package Then, the package establishes a connection using signalr At a certain point, the server triggers a function ...

Creating a channel for communication between sibling components in Angular 4 by storing component references in a shared service

I am searching for a way to establish communication between two sibling Angular 4 components. After reviewing the documentation at https://angular.io/guide/component-interaction, my idea revolves around utilizing a service that stores a reference to the c ...

Typescript libraries built specifically for unique custom classes

I am currently exploring the most effective method for creating a class library in Typescript and deploying it to NPM along with a definitions file. The classes within the library serve as models that are utilized by multiple RESTful services. Some of the ...

Troubleshooting: Angular 7 POST request not communicating with PHP server

Currently, my Angular 7 application is utilizing HttpClient to send a POST request to a PHP server. The process involves a reactive form collecting user input and then transferring it to a specific URL using the following code snippets: admin.component.ts ...

The webpage at 'https://abcd.ac.in/' has been declined to be displayed in a frame due to the 'X-Frame-Options' being set to 'sameorigin'

When attempting to load a website within an iframe, I encountered an error in the console stating "Refused to display 'https://abcd.ac.in/' in a frame because it set 'X-Frame-Options' to 'sameorigin'. Despite trying other alte ...

Issue with getStaticProps in Next.js component not functioning as expected

I have a component that I imported and used on a page, but I'm encountering the error - TypeError: Cannot read property 'labels' of undefined. The issue seems to be with how I pass the data and options to ChartCard because they are underline ...

What would be the optimal type for the second argument of the `simulate` method?

When using the simulate function, I am familiar with code like this: simulate("change", { target: { value: '7' } }); However, if my onChange function requires an object as a parameter, what should I pass in the second argument? interface myObj ...

Angular 5 - Inconsistent page refreshing when navigating instead of real-time DOM updates

I recently started a brand-new Angular 5 project and set up routing by following the instructions in the Angular Documentation. However, I encountered an issue where instead of updating the DOM, the page was refreshing when navigating between routes. Here ...