1

I have following problem:

export class FloorManagerComponent implements OnInit
{
    public meta = {
        list: [],
        building: Building,
        loading: true,
    };

    constructor(
        private router: Router, 
        private activatedRoute: ActivatedRoute, 
        private buildingService: BuildingService
    )
    {;}

    public async ngOnInit() 
    {
        let params = await this.activatedRoute.params.first().toPromise();

        this.meta.building = await this.buildingService // line 42: ERROR
            .getBuilding(params['buildingId'])          // line 42: ERROR
            .toPromise();                               // line 42: ERROR
    }

    ...
}

I get following error during compilation:

[at-loader] ./src/pages/floor/manager/floorManager.component.ts:42:9 TS2322: Type 'Building' is not assignable to type 'typeof Building'. Property 'prototype' is missing in type 'Building'.

Im stuck here - any idea?

Here are body of used classes:

export class Building {

    constructor(
        public id: number,
        public name: string, 
        public image_url: string, 
    ) {}

    ...
}


export class BuildingService {

    public getBuilding(buildingId: number)
    {
        return this.http.get(Url.api('buildings/' + buildingId))
            .map( (response) => { 
                return Obj.cast(response, Building);                  
            } );
    }

    ...

}

export class Obj {

    /**
     * This method allow to cast json (and not only) obiects to given type including methods
     * CAUTION: Constructor of 'type' T of object obj is never call during casting
     * Example usage:
     *
     * let space: Space = this.cast(spaceFromJson,Space);
     *
     * (we use type: { new(...args): T} tp creeate fat arrow functions in prototpye...  https://stackoverflow.com/a/32186367/860099)
     *
     * @param obj object (from json) that has only fields and no methods
     * @param type desired type
     * @returns {any} object that hava fields from obj and methods from type
     */
    public static cast<T>(obj, type: { new(...args): T} ): T 
    {
        obj.__proto__ = type.prototype;
        return obj;
    }
    ...
}
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • 1
    you dont need explicit casting to convert the json to typeof `Building` .. just use `return response.json()` from the `getBuilding` method and use `.then` in the component. if the response matches the property and datatype of the class `Building` it will be typecasted automatically. – Niladri Feb 04 '18 at 11:16
  • 1
    @Niladri no because Building class has also METHODS - if I not made type casting then I will unable to use those methods. Second thing - I use await/toPromist construction to avoid code in 'nested way' (by use '.then') - last thing: I try your solution - NOT WORKING - problem still appearrs – Kamil Kiełczewski Feb 04 '18 at 13:08
  • 1
    @KamilKiełczewski casting will only tell the compiler that you have the right Type. It will not add any functions and will crash if you call those functions. You should ```return new Building(response. response.name, response.image_url);```. It won't solve the issue you have but it will allow you to use the functions on Building. Sorry didn't see your cast Obj. – JGoodgive Feb 04 '18 at 13:59
  • @JGoodgive - no - look on attached code in question - I use static cast method Obj.cast (in BuildingService) to do the job of casting type WITH methods. – Kamil Kiełczewski Feb 04 '18 at 21:59
  • Yeah saw that Kamil. Added it to my comment at the end. Its interesting your code. I will look at it when i have slept. – JGoodgive Feb 04 '18 at 23:23
  • @kamilkielczewski could it be in how the class is typed as an object with a constructor fn. Which is a model for a class but does indeed miss the prorotype property? Does it still accept the class if you add the prototype property to the type of your ```{ new(...args):T}``` – JGoodgive Feb 04 '18 at 23:40
  • I don't know answer to your questions however I test above Obj.cast class and it works. But I ask this question in stack overflow: https://stackoverflow.com/q/48616480/860099 – Kamil Kiełczewski Feb 05 '18 at 05:48

1 Answers1

1

I found solution:

public meta = {
    list: [],
    building: null as Building,
    loading: true,
};

So we should change building: Building to building: null as Building. Because we use "object notation" in meta field definition the mistake was that I use "non-object notation" on subfield building (in "object notation" the : change meaning from type to value definition).

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345