Error: The function being called in <class> is not recognized as a function

I have a unique situation with my component setup

export class Component1Component implements OnInit {

public greetings: string ="";

constructor(private greeter: Greeter) { }

ngOnInit() {
   this.greetings =  this.greeter.sayHello();
}

} 

The structure of the Greeter class is as follows:

export class Greeter{ 
  private hello_greetings = "Hello";
  constructor(){} 
  public sayHello():string {
    return this.hello_grittings;
  }
 }

A factory provides the Greeter class:

export function GreeterFactory():Greeter { return new Greeter(); }

@NgModule({
    providers: [                               
        { provide: Greeter,          
          useFactory: GreeterFactory,
          multi: true                       
        }
  ]
})

Upon loading Component1, I encounter the following error:

AppComponent.html:1 ERROR TypeError: this.greeter.sayHello is not a function at Component1Component.ngOnInit (component1.component.ts:36)

When printing this.greeter in the OnInit method, the output is:

[{"hello_greetings":"Hello"}]

It appears that the class is being injected correctly, but the methods are not found during runtime. Any assistance would be greatly appreciated.

You can access the entire project here

Thank you for your help!

Answer №1

Make sure to eliminate the multi: true setting in the provider configuration. This setting signifies that the object will be treated as an array during injection. As evident from your console display, the output is [{"hello_greetings":"Hello"}] (observe the [] brackets).

Answer №2

By using the option multiple: true in your Greeter service, you are allowing multiple instances of the service to be injected as an array.

To only allow a single instance, you need to modify the multi: true to either multi: false or remove it altogether.

Answer №3

The reason for this occurrence is due to the fact that the variable greeter is an array consisting of instances of the class Greeter. In order for the types to align correctly, it should be injected in the following manner:

constructor(@Inject(Greeter) private greeter: Greeter[]) { }

As mentioned in the documentation,

multi?: boolean

If set to true, the injector will return an array of instances. This feature is useful for situations where multiple providers from different files need to provide configuration data to a shared token.

If the intention is to use multi-providers, then the method should be called on one of the instances like so: this.greeter[0].sayHello(). If not, then there is no need to specify multi.

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

Mongodb Dynamic Variable Matching

I am facing an issue with passing a dynamic BSON variable to match in MongoDB. Here is my attempted solutions: var query = "\"info.name\": \"ABC\""; and var query = { info: { name: "ABC" } } However, neither of thes ...

Tests in Angular2 are executed before the variables in compileComponents are initialized

I'm encountering an issue with an Angular2 text component where I receive the following error message when trying to run the testrunner: Component: Product Component Should ensure component subscribes to service EventEmitter on instantiation Failed: ...

Exploring Angular 2: Unlocking the Power of Directives within Components

To display a dialog component on the main component page after clicking a button, I used directives in the following way: Within the template: <button id="goToTasksCases" class="btn btn-success btn-lg" (click)="doShowStartNewCase($event)">START A N ...

ReactForms Deprication for NgModel

According to Angular, certain directives and features are considered deprecated and could potentially be removed in upcoming versions. In a hypothetical scenario, let's say I am using NgModel with reactive forms, which Angular has marked as deprecate ...

Creating a custom type for the parameter of an arrow function in Typescript

I need assistance defining the type for an object parameter in an arrow function in TypeScript. I am new to TypeScript and have not been able to find any examples illustrating this scenario. Here is my code: const audioElem = Array.from(videoElem.pare ...

How to connect a form component object with a parent object in Vue3 using v-model and the Options API?

My inquiry is quite straightforward. I am exploring the official Vue documentation that delves into v-model arguments in relation to forms within a child component. Here is the code snippet I am referring to: (App.Vue) <script> import UserName from & ...

Angular15 experiencing issues with Grid from Bootstrap

I am attempting to create a basic webpage using the bootstrap grid system, but I am encountering some issues with its functionality. Here is the code from my app-component.html file: <body> <div class="container"> <div class=& ...

Struggling to find the definition of a Typescript decorator after importing it from a separate file

Consider the following scenario: decorator.ts export function logStuff(target: Object, key: string | symbol, descriptor: TypedPropertyDescriptor<any>) { return { value: function (...args: any[]) { args.push("Another argument ...

The Swagger-ui tool condenses objects into query parameters, while the angular client that it generates does not

I'm currently working on a Spring Boot application that includes the following Rest function: @SecuredMaster @GetMapping(path = "/mitarbeiter") @Operation(security = {@SecurityRequirement(name = "jwt")}) public Page<MitarbeiterListRow> getMitar ...

Is it recommended for TypeScript to automatically resolve the index.ts file as the default module file?

Struggling with getting the module resolution to work in TypeScript. Consider the following file structure: /modulename/index.ts Should it be resolved like this? import * as modulename from "modulename" I can't seem to make it work. However, imp ...

Unable to locate a compatible version for caniuse-lite with the specified range of ^1.0.30001349

I encountered an error while running npm install: npm ERR! code ETARGET npm ERR! notarget No matching version found for caniuse-lite@^1.0.30001349. npm ERR! notarget In most cases you or one of your dependencies are requesting npm ERR! notarget a package v ...

Animating Angular on the table row element

I am currently displaying a table with a list of items that are updated via polling using an http get request to the server. The response is rendered only if there have been changes in the data. My goal is to add animations to the rows of the table and tr ...

Creating a dynamic multi-line list in Ionic application is a breeze!

I'm a beginner in Ionic and I am interested in creating a Multi-line List similar to how we generate list-views in Android with custom views and using an Array of custom objects programmatically. Can Multi-line Lists be generated with data from an Ar ...

What is the solution for resolving array items in a GraphQL query?

I am facing an issue with my graphql Query, specifically in trying to retrieve all the fields of a Post. { getSpaceByName(spaceName: "Anime") { spaceId spaceName spaceAvatarUrl spaceDescription followin ...

Angular code for opening a PDF from an API response in a new tab

It's been nearly three days and I could really use some assistance with this issue I'm facing. Inside my Node application, there is an API call that utilizes HTTPS to connect to an external API and retrieve a PDF file. The PDF code snippet looks ...

What is the recommended TypeScript type for setting React children?

My current layout is as follows: export default function Layout(children:any) { return ( <div className={`${styles.FixedBody} bg-gray-200`}> <main className={styles.FixedMain}> <LoginButton /> { children } ...

What is the best approach to integrating payment solutions into a React Native application running on version 0

Seeking advice on integrating payment systems in React Native 0.70. Previously utilized react-native-credit-card-input and react-native-credit-card-input-plus with earlier versions, but they are now incompatible. ...

Is there a way to inject 'cmd' into the browser for Sentry (@sentry/nextjs package) by using a personalized webpack setup in Next.js?

My package json includes the following dependencies: "webpack": "5.58.1", "@sentry/nextjs": "6.13.3", "typescript": "4.0.5", "next": "11.0.1", After running next build without ...

ContentChildren to gather all offspring

Currently, I am in the process of compiling a list of components using data from the Back End. I have implemented a ContentChild object to obtain their reference, however, it seems to be empty. I also attempted using ViewChild, but it only captures the fir ...

What is the best approach for implementing recursion within a foreach loop in TypeScript?

Problem Situation I am attempting to develop a customized typewriting effect similar to the one demonstrated here with a 100ms delay using Angular. The TypeScript code I have written for this purpose is as follows: private arr: string[] = ["Lead Dev ...