Class's Set throws Cannot invoke an expression whose type lacks a call signature using BehaviorSubject and Observable

Viewed 2176

as stated in the title, I'm getting the following error when trying to set a new Item:

Cannot invoke an expression whose type lacks a call signature. Type 'ItemModel' has no compatible call signatures.

I'm using BehaviorSubject and Subject to share a set Item between two different states. Essentially, I want to set a chosen Item and then, when going to its details page, get it.

Here's my item.model.ts, let's suppose it has only an id property:

export class ItemModel {
    public id: string;
    constructor( id: string ) {
        this.id = id;
    }
}

Here's my item.service.ts use to get and set an Item:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { ItemModel } from './item.model';

@Injectable()
export class ItemService {

    public _item = new BehaviorSubject<ItemModel>(null);
    item$ = this._item.asObservable();

    public set item(item: ItemModel) {
        this._item.next(item);
    }

    public get item() : ItemModel {
        return this._item.getValue();
    }

}

My item.component.ts would set a given Item:

import { Component } from '@angular/core';
import { Router } from '@angular/router';

import { ItemService } from '../item.service';

@Component({
    selector: 'app-item',
    templateUrl: './item.html',
    styleUrls: ['./item.scss'],
    providers: [ItemService]
})

export class ItemComponent {

    constructor(private _router: Router, private _itemService : ItemService) { }

    goToDetails(item : ItemModel){
       this._itemService.item(item); //Throws the error
       this._router.navigate(['/details', item.id]);
    }

}

And on details.page.ts I want to get that Item:

 import { Component } from '@angular/core';
 import { Subscription } from 'rxjs/Subscription';
 import { ItemService } from './item.service';
 import { ItemModel } from './item.model';

 @Component({
     selector: 'app-details-page',
     templateUrl: './details.page.html',
     styleUrls: ['./details.page.scss'],
     providers: [ItemService]
 })

 export class DetailsPage {

     private _item = ItemModel;
     private subscription : Subscription;

     constructor( private _itemService: ItemService ) { }

     ngOnInit() {

         this.subscription = this._itemService.item$
             .subscribe(item => console.log(item));

     }

 }

What I tried so far on the invocation of the setter:

  • item as ItemModel
  • item as typeof ItemModel
  • Other solutions coming from this answer by @Sefe and many more
  • Checking a lot of issues opened on Typescript's GitHub Issues like this one

What Am I doing wrong? How can I make sure that ItemModel has a compatible signature?

EDIT

With @n00dl3 's help I was able to get rid of this error. But, unluckily, when logging inside details.page.ts's ngOnInit I get null. When I log inside the setter it shows the correct output.

1 Answers
Related