4

I am writing a Javascript API library that provides consumers with an interface that enables them to interact with our backend web services. It is envisioned that a consumer will be writing a javascript client web application that draws heavily on the API provided for by the library.

I have come up with this "pattern" for maintaining state and making functionality "available" as certain criteria are met (for example, an authenticated user is logged in client-side).

Is this an appropriate way to achieve that end? Or am I unwittingly breaking some convention or best practice that will bite me later on?

// file: clientApi.js (library)

ClientObject = function () {
    this.objectname = "a client class";
}

ClientObject.prototype.loginUser = function(name) {
    this.loggedin = true;
    if (typeof this.User === 'undefined') {
        this.User = new ClientObject.User(name);
    }
}
ClientObject.User = function (name) {
    this.username = name;
}

ClientObject.User.prototype.getProfile = function() {
    return 'user profile';
}

// file: app.js (consuming application)

var testClient = new ClientObject();
console.log('testClient.User = ' + (typeof testClient.User)); // should not exist
testClient.loginUser('Bob'); // should login 'bob'
console.log('testClient.User = ' + (typeof testClient.User)); // should exist
console.log(testClient.User.username); // bob
testClient.loginUser('Tom'); // should not do anything
console.log(testClient.User.username); // bob still
console.log(testClient.User.getProfile()); // tada, new functionality available

My question: is this approach valid? Is there a pattern that I'm touching on that might offer a better explanation or method of achieving my end goal?

I asked a similar question here with a bunch of other ones, unfortunately the above code was somewhat lost in the noise: Javascript: creation of object from an already instantiated object versus the prototype

1 Answer 1

2

Your API should have some secrets. That's why do not make all your functions public. Let's analyze some parts of your code:

testClient.loginUser('Tom'); // should not do anything

But your implementation allows client to do next:

testClient.User = new ClientObject.User(name);

Now user will be changed to "Tom".

Let's change your clientApi.js code, using revealing prototype pattern:

ClientObject = function () {
    this.objectname = "a client class";
    this.username;
    this.User;
    this.loggedin;
 }    

ClientObject.prototype = function() {  
var loginUser = function(name) {
    this.loggedin = true;
    if (typeof this.User === 'undefined') {
        this.User = new User(name);
    }
};

var User = function (name) {
    this.username = name;
};

User.prototype.getProfile = function() {
    return 'user profile';
};

return {
    loginUser : loginUser
}
}()

Now client cannot change logged in User like in first version of the library. You can use some variations, but that's the idea.

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.