1

I am trying to convert the keys iterable from a map but when i do so I get the error:

statistics.produceTypeData.keys is not a function

I am following the answer of this question: How to convert Map keys to array? to make it work.

When i try the alternative approach (using Array.from(statistics.produceTypeData.keys())) i get a different error, namely:

Type 'IterableIterator' is not an array type.

In the comments i've read that in this case one should enclose the Array.from() statement in spread syntax but when i do that i also get the error statistics.produceTypeData.keys is not a function.

Here are the code snippets:

  produceTypeLabels: ProduceType[];
      this.produceTypeLabels = [...Array.from(statistics.produceTypeData.keys())]; 

The ProduceType enum:

export enum ProduceType {
    FRUIT = "FRUIT",
    VEGETABLE = "VEGETABLE",
    HERB = "HERB",
    NUT = "NUT",
    SEED = "SEED",
    MUSHROOM = "MUSHROOM",
    CACTUS = "CACTUS"
}

the statistics object comes from a get request and looks like this:

export class DatabaseStatisticsDTO {
    produceTypeData: Map<ProduceType,number>;
    plantTypeData:  Map<PlantType,number>;
    lifeCycleData:  Map<LifeCycleType,number>;
    sunExposureData:  Map<SunExposure,number>;
    ripeColorData:   Map<Color,number>;
    frostResistanceData: Map<boolean,number>;
    teaPlantData: Map<boolean,number>;
    climbingPlantData: Map<boolean,number>; 
    pepperData: Map<boolean,number>; 
}

Does anyone know why i am getting these errors? I know i could simply iterate over the keys iterable and fill an array that way but i would really like to do it with either the spread syntax or the Array.from() function.

Thank you

EDIT:

This is the stacktrace from the debugger when i try to use the spread syntax with statistics.produceTypeData.keys()

RROR TypeError: statistics.produceTypeData.keys is not a function
    at SafeSubscriber._next (database-statistics.component.ts:65)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:195)
    at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:133)
    at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)
    at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterSubscriber._next (filter.js:38)
    at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:79)

EDIT 2: Changed DatabaseStatisticsDTO so that map fields are initialized with empty Map objects, the fields are still undefined after the get request though.

export class DatabaseStatisticsDTO {
    produceTypeData: Map<ProduceType,number> = new Map<ProduceType,number>();
    plantTypeData:  Map<PlantType,number> = new Map<PlantType,number>();
    lifeCycleData:  Map<LifeCycleType,number> = new Map<LifeCycleType,number>();
    sunExposureData:  Map<SunExposure,number> = new Map<SunExposure,number>();
    ripeColorData:   Map<Color,number> = new Map<Color,number>();
    frostResistanceData: Map<boolean,number> = new Map<boolean,number>();
    teaPlantData: Map<boolean,number> = new Map<boolean,number>();
    climbingPlantData: Map<boolean,number> = new Map<boolean,number>();
    pepperData: Map<boolean,number> = new Map<boolean,number>(); 
}

This is the code that makes the get request:

  getStatistics():Observable<DatabaseStatisticsDTO>{
    return this.http.get<DatabaseStatisticsDTO>(this.apiUrl + "/mod/getstatistics");
  }
23
  • It might help reproduce the problem if you could show us statistics.produceTypeData Commented Jul 20, 2018 at 16:40
  • 1
    If it really comes "from a get request" it doesnt have Maps. Commented Jul 20, 2018 at 16:41
  • 1
    Do you perhaps target ES5 or lower? Commented Jul 20, 2018 at 16:47
  • 2
    in order to create Map you have to create it like via Map constructor. If you haven't done any deserialization on json, all maps in json will be just object literals not Maps Commented Jul 20, 2018 at 16:47
  • 1
    @Maurice I think you need to log produceTypeData to the console (or the debugger) and look at it. It's not what you think it is. Commented Jul 20, 2018 at 16:49

1 Answer 1

1

ok i solved the issue. The problem was that i was expecting an object with map objects in it, however what they really contained were object literals that needed to be converted to Map objects first. The code looks like this now:

  this.produceTypeLabels = Object.keys(statistics.produceTypeData); 
  this.produceTypeData  = (<any>Object).values(statistics.produceTypeData).map(a => Number(a));
  this.produceTypeBackgroundColors = ["#9400D3","#0000FF","#00FF00"];

I am using Object.keys to get the key part from the object literal and (<any>Object).values for the values. The reason why i'm using (<any>Object) instead of just Object is because i don't have the ES2017 library installed. I tried doing it but still got a warning that values() wasn't a function of object. As an alternative one can use (<any>Object)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.