1

I'm trying to use the map function of the array to map my data to a specific class. The project is in Angular.

So I do:

me.$http({
    url: me.appConfig.api + `customer/${customer.number}/stock/warehouses`,
    method: 'get'
}).then((r: any) => {
    def.resolve(r.data.map(Warehouse));
}).catch(def.reject);

Pretty basic so far. Then in my Warehouse class it looks like this:

export class Warehouse {
    code: string;
    location: string;
    weight: number;
    count: number;
    late: number;

    stock?: Stock[];

    constructor(data?: any) {
        console.debug('test', data);
        this.code = 'test';
        if (data) {
            this.code = data.code;
            this.location = data.location;
            this.weight = data.weight;
            this.count = data.count;
            this.late = data.late;
        }
    }
}

So just a copy of the values, but the weird thing is, it already errors on the this.code = 'test' then I get the error:

TypeError: Cannot set property 'code' of undefined
    at Warehouse (main.bundle.js:2218:19)
    at Array.map (native)

Any clue why this is happening?

Sample data:

[
  {
    "code": "SQD",
    "location": "35,16161;6,31561",
    "weight": 3200,
    "count": 18,
    "late": 18
  },
  {
    "code": "GQZ",
    "location": "35,16161;6,31561",
    "weight": 321,
    "count": 20,
    "late": 18
  }
]
Kiwi
  • 2,713
  • 7
  • 44
  • 82
  • Can you share sample `data`? Also I guess issue is with `this` and not with `data` – Rajesh Dec 30 '16 at 09:27
  • yea, the problem lies with the 'this', that's why I did the `this.code = 'test'`, which failed – Kiwi Dec 30 '16 at 09:30
  • 2
    In my understanding, you will have to so something like `.map(x=>new Warehouse(x))` – Rajesh Dec 30 '16 at 09:31
  • I think since you are passing in a constructor, not an object, `this` doesn't exist in that context. – Ahmad Baktash Hayeri Dec 30 '16 at 09:32
  • Your map simply calls warehouse, you need to construct a new Object using new Warehouse – Jonas Wilms Dec 30 '16 at 09:37
  • Avoid the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Dec 30 '16 at 11:08
  • If you had used an actual ES6 environment and not a sloppy transpiler, you'd get a proper error message that `class` constructors need to be called with `new`. `map` doesn't do that. – Bergi Dec 30 '16 at 11:09
  • @Rajesh yep that did it, will you reply so I can accept? :) – Kiwi Jan 03 '17 at 11:56
  • @Kiwi Its alright! Glad, I was able to help! If you need any clarification, please tag – Rajesh Jan 03 '17 at 11:58

1 Answers1

0

You appear to be passing a constructor into the array map function, which is probably not what you want

def.resolve(r.data.map(Warehouse));

should probably be

def.resolve(new Warehouse(r.data));

the function r.data.map(FN) takes a function and returns an array that results from taking each element E of r.data and calling the function with E as the parameter, as in FN(E). see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map