Angular 2's Dependency Injection injects functions instead of objects

My application has a 'store' service that depends on a 'repo' service. The issue I'm facing is that the 'store' service is being injected correctly, but the 'repo' service it receives appears to be a function instead of an object. I suspect that this might be related to the order in which the JavaScript code is executed, but I have not been able to pinpoint the exact cause.

For search engines: The error message I encounter states "'XXX' is not a function" when attempting to access a function on the injected repo.

Below is some sample code for reference:

app.module:

import { ServiceCallListComponent } from './service-call-list/service-call-list.component';
import { AppComponent } from './app.component';
import { ServiceCallsDataRepository } from './data/service-call.repo'
import { SERVICE_CALLS_DATA_REPO } from './data/service-call.repo.token'
import { LocalServiceCallsDataRepository } from './data/service-call.repo.local';
import { ServiceCallsStore } from './data/serivce-call.store';

@NgModule({
  declarations: [
    AppComponent,
    ServiceCallListComponent,
  ],
  imports: [... ],
  bootstrap: [AppComponent],
  providers: [{ provide: SERVICE_CALLS_DATA_REPO, useValue: LocalServiceCallsDataRepository },
    ServiceCallsStore, LocalServiceCallsDataRepository,

  ],
})
export class AppModule { }

service-call.store

import { Injectable, Inject } from '@angular/core';
import { Observable, Observer, Subject, BehaviorSubject } from 'rxjs/rx';
import { ServiceCall } from './service-call.model'
import { ServiceCallsDataRepository, StoreResultsRange } from './service-call.repo'
import { SERVICE_CALLS_DATA_REPO } from './service-call.repo.token'
import { LocalServiceCallsDataRepository } from './service-call.repo.local'

@Injectable()
export class ServiceCallsStore {
   // repo: LocalServiceCallsDataRepository;
    constructor( @Inject(SERVICE_CALLS_DATA_REPO) private repo: ServiceCallsDataRepository) {
    //     constructor(  private repo: LocalServiceCallsDataRepository) {
        //constructor() {
         //this.repo=new LocalServiceCallsDataRepository();
    }

    public getSerivesCallsObservable(filter: BehaviorSubject<string>, range: Observable<StoreResultsRange>): Observable<Array<ServiceCall>> {
        let b = this.repo.getServiceCalls2();
        let observable = filter.map(fltr => this.repo.getServiceCalls2().filter(sc => sc.name.indexOf(fltr) > -1));
        // range.subscribe(rng => this.repo.load(filter.getValue(), rng))
        return observable;
    }

    public add(serviceCall: ServiceCall): void {
        this.repo.add(serviceCall);
    }
}

service-call.repo

   import { Injectable, Inject } from '@angular/core';
    import { Observable, Observer, Subject, BehaviorSubject } from 'rxjs/rx';
    import { ServiceCall } from './service-call.model'
    import { ServiceCallsDataRepository, StoreResultsRange } from './service-call.repo'
    import { SERVICE_CALLS_DATA_REPO } from './service-call.repo.token'
    import { LocalServiceCallsDataRepository } from './service-call.repo.local'

    @Injectable()
    export class ServiceCallsStore {
                constructor( @Inject(SERVICE_CALLS_DATA_REPO) private repo: ServiceCallsDataRepository) {
        //     constructor(  private repo: LocalServiceCallsDataRepository) {
        }

        public getSerivesCallsObservable(filter: BehaviorSubject<string>, range: Observable<StoreResultsRange>): Observable<Array<ServiceCall>> {
            let b = this.repo.getServiceCalls2();
            let observable = filter.map(fltr => this.repo.getServiceCalls2().filter(sc => sc.name.indexOf(fltr) > -1));
            // range.subscribe(rng => this.repo.load(filter.getValue(), rng))
            return observable;
        }

        public add(serviceCall: ServiceCall): void {
            this.repo.add(serviceCall);
        }
    }

service-call.repo.local

import { Injectable, Inject } from '@angular/core';
import { Observable, Observer, Subject, BehaviorSubject } from 'rxjs/rx';
import { ServiceCall } from './service-call.model'
import { ServiceCallsDataRepository,StoreResultsRange } from './service-call.repo'

@Injectable()
export class LocalServiceCallsDataRepository implements ServiceCallsDataRepository {
    private data: Array<ServiceCall> = new Array<ServiceCall>();
    private serviceCalls = new BehaviorSubject<Array<ServiceCall>>(new Array<ServiceCall>());
    constructor() {
    }

    public getServiceCalls2(): Array<ServiceCall> {
        return this.data;//this.serviceCalls.getValue();
    }

    public add(serviceCall: ServiceCall): void {
        throw "not implemented";
    }

    public load(filter: string, range: StoreResultsRange): void {
        throw "not implemented";

        //this.serviceCalls.next(this.data);
    }
}

service-call.repo.token

import { OpaqueToken } from '@angular/core';

export let SERVICE_CALLS_DATA_REPO = new OpaqueToken('SERVICE_CALLS_DATA_REPO');

Answer №1

Consider utilizing useClass over useValue. Here's an example:

{ provide: DATA_REPOSITORY_SERVICE, useClass: LocalDataRepository }

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

The Angular CLI is unable to generate a project and needs npm@6 to be installed

Every time I run ng new first-project, it keeps showing me the following message: A compatible npm version was not detected. The Angular CLI currently requires npm version 6 to function properly. To proceed, please ensure you have npm version 6 installed ...

Testing a NestJS service with multiple constructor parameters can be done by utilizing various techniques such as dependency

Content When testing a service that needs one parameter in the constructor, it's essential to initialize the service as a provider using an object instead of directly passing the service through: auth.service.ts (example) @Injectable() export class ...

React function failing to utilize the latest state

I'm facing an issue with my handleKeyUp function where it doesn't seem to recognize the updated state value for playingTrackInd. Even though I update the state using setPlayingTrackInd, the function always reads playingTrackInd as -1. It's p ...

Is there a way to merge TypeScript code with C++ during compilation?

Currently, I have a project written entirely in C++. However, there is an additional file written in typescript because I couldn't find equivalent libraries in C++. This typescript file performs the following actions: It contains a typescript CLI cod ...

Tips on how child component can detect when the object passed from parent component has been updated in Angular

In the child component, I am receiving an object from the parent component that looks like this: { attribute: 'aaaa', attribute2: [ { value }, { value }, { value }, ] } This object is passed to th ...

Utilize Page.evaluate() to send multiple arguments

I am facing an issue with the Playwright-TS code below. I need to pass the email id dynamically to the tester method and have it inside page.evaluate, but using email:emailId in the code throws an undefined error. apiData = { name: faker.name.firstNa ...

What could be causing the issue where I am receiving the error message that says: "Unable to access properties of undefined (reading 'index')"?

Here is the code snippet from my template: <mat-tab-group mat-align-tabs="start" (selectedTabChange)="ngOnInit($event)"> This is the ngOnInit function: ngOnInit(evt: any) { this.api.getApi().subscribe( ({tool, beuty}) => ...

What is the best way to retrieve the subclass name while annotating a parent method?

After creating a method decorator to log information about a class, there is a slight issue that needs addressing. Currently, the decorator logs the name of the abstract parent class instead of the effectively running class. Below is the code for the deco ...

Is it possible to merge arrays of angular modules together?

I have a challenge where I am attempting to merge two arrays of ngx modules and export them as a unified array. Here is an example of what I'm trying to achieve: @NgModule({ declarations: [], exports: [ CommonModule, FormsModule, ReactiveForm ...

Unable to call an object that may be 'undefined': Utilizing a function with a return object that includes asynchronous functions as properties

I have a function exported in my adapter.ts file: import type { Adapter } from "@lib/core/adapters"; export default function MyAdapter (): Adapter { return { async createUser (user: User) { ... }, async findUserByEmail (email ...

Discovering a specific property of an object within an array using Typescript

My task involves retrieving an employer's ID based on their name from a list of employers. The function below is used to fetch the list of employers from another API. getEmployers(): void { this.employersService.getEmployers().subscribe((employer ...

Make sure to verify the existence of a value before attempting to render it in Angular 4

I am currently working on a project that involves Angular 4. Here is an example of the code I am using : <div *ngFor="let item of results"> <p> {{item.location.city}} </p> <p> {{item.location.country}} </p> </div> T ...

Passing a Typescript object as a parameter in a function call

modifications: { babelSetup?: TransformationModifier<babel.Configuration>, } = {} While examining some code in a React project, I came across the above snippet that is passed as an argument to a function. As far as I can tell, the modifications p ...

I'm searching for TypeScript interfaces that can be used to define OpenAPI Json. Where can I

If you're looking to implement the OpenApi specifications for your project, there are a variety of fields and values that need to be set. For a detailed look at these specifications, you can refer to the documentation here. In an effort to streamline ...

Tracking events in Angular 4 using angulartics2 and Adobe Analytics: A step-by-step guide

I've been working on tracking page views in my Angular 4 application, specifically with Adobe Analytics. Currently, I am utilizing angulartics2 for this purpose. First step was adding the necessary script for Adobe Staging in my index.html page: &l ...

Unable to determine model dependency in Nest

I encountered an issue where Nest is unable to resolve dependencies. The error message from the logger reads as follows: [Nest] 39472 - 17.08.2023, 05:45:34 ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserTransactionRepository ( ...

Encountered an ERROR when attempting to deploy a next.js app to Azure Static Webapp using GitHub actions for

I am encountering an issue that is causing some frustration. The problem only arises during my github actions build. Interestingly, when I run the build locally, everything works perfectly and I can access the route handler without any issues. However, eve ...

Exploring Angular: Enhancing Routing through GET Requests

I've been working on a cutting-edge application that combines an Angular 2 frontend with a powerful Java backend. An exciting feature of this application is a dynamic form, consisting of various search criteria. Upon submission, I execute an http get ...

Encountering error TS2307 while using gulp-typescript with requirejs and configuring multiple path aliases and packages

Currently, I am working on a substantial project that heavily relies on JavaScript. To enhance its functionality, I am considering incorporating TypeScript into the codebase. While things are running smoothly for the most part, I have encountered an issue ...

Converting an IEnumerable of XElement into a List of Objects within an IActionResult: A Comprehensive Guide

I am struggling to figure out how to return a List in my ASP.NET Core CRUD method. It needs to return List<BookItem>. The search part of the method seems to be working fine as it returns a list of IEnumerable<XElement> that contains strings, I ...