The expression you are trying to invoke does not have a call signature. The type 'UserModel' does not have any compatible call signatures available for invocation

I encountered a type error while attempting to set a property in my user.service.ts. Here is the code snippet from user.service:

import { Injectable } from '@angular/core';
import { UserModel } from '../models/user.model';

@Injectable()
export class UserService {
  private _user: UserModel;
  constructor() {}

  get getUser(): UserModel {
    return this._user;
  }
  set setUser(user: UserModel) {
    this._user = user;
  }
}

This is the structure of UserModel:

export class UserModel {
  constructor(public uid: string,
              public displayName: string,
              public email: string,
              public photoUrl: string,
              public providerId: string) {}
}

The issue arises in the auth.service file where I am encountering the error.

import {Injectable} from '@angular/core';
import * as firebase from 'firebase';
import { AngularFireAuth } from 'angularfire2/auth';
import {Router} from '@angular/router';
import { UserModel } from '../models/user.model';
import { UserService } from './user.service';


@Injectable()
export class AuthService {
  private _token: string = null;

  private _firstLogin = false;
  constructor(private afAuth: AngularFireAuth,
              private router: Router,
              private userService: UserService) {}

  get isFirstLogin() {
    return this._firstLogin;
  }
  get getUserToken(): string{
    return this._token;
  }
  set setUserToken(tk: string) {
    this._token = tk;
  }

  // Sign in with Facebook method
  signinWithFacebook(): Promise<any> {
    const fbProvider = new firebase.auth.FacebookAuthProvider();
    return this.signin(this.afAuth.auth.signInWithPopup(fbProvider));
  }

  signin(popupResult: Promise<any>): Promise<any> {
    return popupResult
      .then(
        (res) => {
          this._firstLogin = true;
          const user: firebase.User = res.user.toJSON();
          const credential = res.credential;
          this._token = credential.accessToken;

          // Creating an instance of UserModel and passing it to userService's property (_user)
          const providedData = user.providerData[0];
          const buildedUser = new UserModel(providedData.uid, providedData.displayName,
            providedData.email, providedData.photoURL, providedData.providerId);
          this.userService.setUser(buildedUser); //THE ERROR OCCURS HERE.

          console.log(this._token);
          console.log(user);
        }
      );
  }
}

The error occurs when trying to pass a UserModel object from auth.service to user.service using the line: this.userService.setUser(buildedUser). Please provide me with a solution and explain why this issue is happening. Thanks!

Answer №1

Eliminate the usage of get and set in your methods within the UserService:

@Injectable()
export class UserService {
  private _user: UserModel;
  constructor() {}

  getUser(): UserModel {
    return this._user;
  }
  setUser(user: UserModel) {
    this._user = user;
  }
}

Avoid utilizing a setter for setUser(). Using a setter could lead to unintended behavior if accessed incorrectly like

this.userService.setUser = buildedUser
. Instead, consider calling it directly as
this.userService.setUser(buildedUser)
, making it function as a regular method.

In retrieving the user, prefer using

const retrievedUser = this.userService.getUser()
over
const retrievedUser = this.userService.getUser
. The former is simply a method call, while the latter implies a getter.


If you still wish to implement getters and setters, maintain the use of get and set, but perhaps rename the methods getUser and setUser to simply user:

@Injectable()
export class UserService {
  private _user: UserModel;
  constructor() {}

  get user(): UserModel {
    return this._user;
  }
  set user(user: UserModel) {
    this._user = user;
  }
}

Subsequently, you can invoke

this.userService.user = buildedUser
or
const retrievedUser = this.userService.user
and the relevant setter and getter functions will be executed.

However, bear in mind that getters and setters are designed to provide the illusion of accessing properties directly, even though they can perform additional tasks beyond simple property retrieval and assignment. If your objective is solely limited to getting and setting properties, opting for a public property named user might be a more straightforward approach:

@Injectable()
export class UserService {
  public user: UserModel;
  constructor() {}
}

This structure allows for operations such as

this.userService.user = buildedUser
or
const retrievedUser = this.userService.user
with minimal complexity.


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 performance may be impacted by the constant recalculation of ngStyle when clicking on various input fields

I am facing a frustrating performance issue. Within my component, I have implemented ngStyle and I would rather not rewrite it. However, every time I interact with random input fields on the same page (even from another component), the ngStyle recalculate ...

The 'format' property cannot be found on the 'Duration' type

When working with TypeScript and trying to utilize "moment-duration-format", I encountered an issue where webpack is constantly throwing errors stating that it cannot locate the "format" method in this line of code: return moment.duration(value, "minutes" ...

the most effective method for including a new field in a formGroup

How can I correctly add a new object property to an Angular formGroup? Currently, my setup looks like this: ngOnInit() { this.form = this.fb.group({ // store is the formGroupname store: this.fb.group({ // branch and code are formControlN ...

Using Angular 2 to assign unique ids to checkbox values

Is there a way to retrieve the value of a checkbox in Angular 2 without needing an additional Boolean variable? I am trying to toggle the enabled/disabled state of an input field based on the selection of a checkbox. While I know this can be accomplished ...

Concealing applicationId and clientToken in Datadog

I'm currently using an Angular application and I've integrated it with the Datadog application to utilize Session and Replay (RUM). However, I am concerned about the security of my sensitive information such as applicationId and clientToken. Is t ...

Update TypeScript definitions in version 2.2.2 obtained from NPM @Types

I am currently utilizing the component react-router-bootstrap along with the definitions from DefinitelyTyped. However, the downloaded definitions do not align with the component. While I have submitted a pull request to rectify this issue, it has not yet ...

Dealing with request errors in Angular with RxJS - catchError() isn't as effective as expected

Update Alert: Problem Solved. Solution Provided Below In my service class, I have the following code snippet: public getListById(id:string): Observable<any[]> { return this.http.get<any[]>(`${BASE_URL.local}/${id}`).pipe( m ...

Exploring Service Injection and Factory Pattern in Angular 8

After going through various articles and official Angular guides, it appears that they were unable to assist me in solving my task. Here's what I wanted to achieve: Imagine having an Angular application with a product listing page. Additionally, this ...

Mismatch between generic types

When working with this code, I encounter a syntax error at m1 and m2. The error message states: Type 'T' is not assignable to Type 'boolean' or Type 'T' is not assignable to Type 'string' interface customMethod { ...

Unable to finish the execution of the ionic capacitor add android command

My current project needs to add android as a supported platform, so I tried running the command: ionic capacitor add android. However, when I run the command, it stops at a prompt asking me "which npm client would you like to use? (use arrow keys)", with ...

Ways to modify this request in order to update the current status

How can I optimize these calls to avoid repeating the same sentence for refreshing the state? I'm not looking for a major overhaul, just some suggestions like putting this call inside a function and invoking it when needed... export const CategoriesPa ...

Trigger an Angular2 component function from an HTML element by simply clicking a button

I'm just starting out with TypeScript and Angular2 and encountering an issue when trying to call a component function by clicking on an HTML button. When I use the **onclick="locateHotelOnMap()"** attribute on the HTML button element, I receive this ...

There was an issue found at line 18 in the backend.service.d.ts file of the node_modules/angular-in-memory-web-api, showing error TS1086 which states that an accessor cannot be declared

I encountered this issue right after installing 'angular-in-memory-web-api'. import { InMemoryDbService } from "angular-in-memory-web-api"; and subsequently, the following error messages appeared: ERROR in node_modules/angular-in-memory-we ...

Creating a dynamic horizontal list of buttons in NativeScript

I am currently diving into the world of NativeScript and I find myself struggling a bit with the MVVM concept, specifically when it comes to binding. I have configured my environment to work with TypeScript. On my HomePage, I am tasked with creating a hor ...

import component dynamically from object in Next.js

Currently, I have a collection of components that I am aiming to dynamically import using next/dynamic. I'm curious if this is achievable. Here's the object in interest: // IconComponents.tsx import { Tick, Star } from 'components ...

Step into the future with Angular 11: Revolutionize your forms with multiple fields

Currently using angular 11 and encountering a challenge with implementing the following functionality: A stepper containing two inputs in a single step, specifically a datepicker and a select dropdown menu. The objective is for the stepControl to validate ...

Error: Cannot assign type 'string' to type 'Moment'

I am presented with an object structured as follows: import { Moment } from 'moment'; export interface INewsletter { id?: number; creationDate?: Moment; email?: string; } export class Newsletter implements INewsletter { constru ...

Issue occurs where the system is unable to recognize a defined variable, despite it being clearly defined

I keep encountering an error message stating that my variable is not defined, even though I have clearly defined it just a few lines above where the error occurs. The reason behind this error is baffling to me, as I cannot identify any potential triggers ...

Navigating back to a specific segment of a dataset while using virtual scrolling

Virtual scrolling is a fantastic way to optimize rendering for large data sets. For this particular scenario, I am making use of the Angular Material CDK APIs to implement this feature. However, a specific requirement needs to be addressed - when a user ...

Using an array of strings as a key in React with TypeScript to access values from state

import React, { useState } from 'react'; interface PropsInterface { keys: string; // name,email,password } const Poster: React.FC<PropsInterface> = (props: PropsInterface) => { const [state, setState] = useState({ name: ' ...