0

Here is the pseudo-code in question: https://jsfiddle.net/yzps2gef/40/

I'm trying to understand why I cannot access an object's properties directly in one scenario (see ISSUE #1 in comments) but I can in another scenario (see ISSUE #2 in comments). I'm failing to see the difference between the two. Thanks!

Here's the fiddle code:

window.DataStore = function () {
    var url = new Url(),
        filters = new Filters(),
        orderBy,
        orderByDir,
        setOrderBy = function (x, y) {
            orderBy = x;
            orderByDir = y;
        },
        getOrderBy = function () {
            return orderBy;
        },
        getOrderByDir = function () {
            return orderByDir;
        };

    return {
        url: url,
        filters: filters,
        orderBy: orderBy,
        orderByDir: orderByDir,
        setOrderBy: setOrderBy,
        getOrderBy: getOrderBy,
        getOrderByDir: getOrderByDir
    };
};

window.Url = function () {
    var get = function (ds) {
        var url = 'xyz.php';

        console.log(ds);

        // ISSUE #1: These do not work.  It results in: xyz.php?orderby=undefined&orderbydir=undefined.
        // Why can't I access them directly like I do below with the dataStore.filters.someFilterOption?
        url = url + '?orderby=' + ds.orderBy;
        url = url + '&orderbydir=' + ds.orderByDir;

        // These work when I use the "get" functions.
        // url = url + '?orderby=' + ds.getOrderBy();
        // url = url + '&orderbydir=' + ds.getOrderByDir();

        return url;
    }

    return {
        get: get
    };
};

window.Filters = function () {
    var someFilterOption = 0;

    return {
        someFilterOption: someFilterOption
    };
};

window.Grid = function () {
    var dataStore = new DataStore(),
        doSearch = function () {
            console.log(dataStore.url.get(dataStore));
        },
        render = function () {
            doSearch();
            // ISSUE #2: Why can I access this one directly but not the order bys?
            if (dataStore.filters.someFilterOption) {
                console.log('Why was I able to read this one (dataStore.filters.someFilterOption) directly and not have to have a getSomeFilterOption() function to read it?  But when it comes to the orderBy and orderByDir above I cannot read them directly.');
            }
        }

    return {
        dataStore: dataStore,
        render: render
    };
};

window.MyReUsableGrid = function () {
    var grid = new Grid(),
        showSomeFilterOption = function () {
            grid.dataStore.filters.someFilterOption = 1;
        },
        render = function () {
            grid.render();
        };

    grid.dataStore.setOrderBy(4, 'asc');

    return {
        showSomeFilterOption: showSomeFilterOption,
        render: render
    };
};

// The Screen
var myGridScreen = new MyReUsableGrid();
myGridScreen.showSomeFilterOption();
myGridScreen.render();

1 Answer 1

1

Because when your object gets returned from the function this line gets evaluated:

 orderBy: orderBy,

And as the variable orderBy isnt set yet it is actually:

 orderBy: undefined

Now later you call setOrderBy and set the internal variable orderBy to a value which you can expose through the getter, but that doesnt get reflected to the objects property.


IMO the whole thing should be restructured so that the methods work with their context:

 window.DataStore = () => ({
    url: new Url(),
    filters: new Filters(),
    applyOrder(order, dir) {
        this.orderBy = order;
        this.orderByDir = dir;
    },
 });

That way you dont need getters at all.

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

4 Comments

Thanks. But then why does grid.dataStore.filters.someFilterOption = 1; work? It is set after the object is returned as well, and it doesn't have a getter function and it's not set using this but I can access it directly in that IF statement and it yields 1, not 0.
@gfrobenius because you mutate the exported object and access the exported object. The internal variable is not really involved
This is working, thank you but I was trying to stick w/ the revealing pattern, less usage of this & very easy to see everything that is public by just looking at the return. In your example, I can't do that. If I set the orderbys your way then I must remove them from the VAR stmnt & the return because they are now created public right there inside the applyOrder func. Correct me if I'm wrong, but couldn't I do exactly what your answer says, except remove the this, & keep them init'ed in the VAR stmnt, & keep them in the return, & that would have the same end result? Thx
Ah, never mind. If I do that then I need the getters. I actually prefer that way (the reveal pattern, everything private except what I reveal in the return, then just use all setters and getters). I think I'll take that approach. But will mark this as the answer because you helped me understand this which is what I was looking for. Thanks!

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.