user4158347
user4158347

Reputation:

JavaScript Classes: Member Defined In Constructor Undefined?

I have a class called UrlBuilder that iterates through a .json file then builds URLs. I can get to the point of looping through the data and printing the correct output, but when I try to push it to an array defined in the classes constructor, I'm told the array is undefined.

Here is my code:

"use strict";
const DATA = require("../resources/data.json").services;

class UrlBuilder {

    constructor() {
        this.serviceArr = [];
    }

    static _iterateAndBuild(current_val, index, array) {
        for(let path of current_val.paths) {
            let url = current_val.baseURL + Object.values(path);
            this.serviceArr.push(url);
        }

        let recHistUrl = current_val.server + current_val.recordHistoryUrl;
        serviceArr.push(recHistUrl);

        console.log("Pushing this value to array: " + recHistUrl);
    }

    buildServiceArr() {
        DATA.forEach(UrlBuilder._iterateAndBuild);
    }

}

module.exports = UrlBuilder;

As you can see, I broke the callback function out of the forEach. So when I call UrlBuilder.buildServiceArr, it loops through the DATA objects and performs the callback written above it.

Here is the output:

C:\Users\payton.juneau\Desktop\Me\Projects\Node\com.etouchmenu.serviceSpyGlass>node app.js C:\Users\payton.juneau\Desktop\Me\Projects\Node\com.etouchmenu.serviceSpyGlass\utilities\urlBuilder.js:13 this.serviceArr.push(url); ^ TypeError: Cannot read property 'serviceArr' of undefined at _iterateAndBuild (C:\Users\payton.juneau\Desktop\Me\Projects\Node\com.etouchmenu.serviceSpyGlass\utilities\urlBuilder.js:13:18) at Array.forEach () at UrlBuilder.buildServiceArr (C:\Users\payton.juneau\Desktop\Me\Projects\Node\com.etouchmenu.serviceSpyGlass\utilities\urlBuilder.js:23:14) at Object. (C:\Users\payton.juneau\Desktop\Me\Projects\Node\com.etouchmenu.serviceSpyGlass\app.js:10:12) at Module._compile (module.js:660:30) at Object.Module._extensions..js (module.js:671:10) at Module.load (module.js:573:32) at tryModuleLoad (module.js:513:12) at Function.Module._load (module.js:505:3) at Function.Module.runMain (module.js:701:10)

Thank you for your time in advance! Probably something dumb like scoping.

Upvotes: 1

Views: 308

Answers (2)

loganfsmyth
loganfsmyth

Reputation: 161457

DATA.forEach(UrlBuilder._iterateAndBuild);

should be

DATA.forEach(UrlBuilder._iterateAndBuild, this);

So that the this from buildServiceArr is passed through as the this of _iterateAndBuild.

As a general stylistic comment, if you have a function that isn't supposed to be public as a static, just put it after the class, e.g.

class UrlBuilder {
    // ...

    buildServiceArr() {
        DATA.forEach(iterateAndBuild);
    }
}

function iterateAndBuild(current_val, index, array) {
    // ...
}

though for your case I'm not sure why it is static and not an instance method, e.g.

class UrlBuilder {
    // ...
    _iterateAndBuild(current_val, index, array) {
      // ...
    }

    buildServiceArr() {
        DATA.forEach(this._iterateAndBuild, this);
    }
}

That would be much more in line with what you're trying to do.

Upvotes: 2

GibboK
GibboK

Reputation: 73918

You should be able to push into your array by using

 this.serviceArr.push(recHistUrl);

Upvotes: 0

Related Questions