0

How does one create an object in Javascript conditional upon a certain condition inside said object. For instance:

function User(email) {

this.email = email;

  this.checkValid = function () {
       // check email if not valid delete the object or return nothing
  }

this.checkValid()

}

var user1 = new User("bob123@aol.com")
eddyrolo
  • 347
  • 1
  • 6
  • Don't. Check the email to be valid before creating the user. – Bergi Jan 24 '15 at 20:42
  • I'm just using that in the example, but say all my functions are inside the object, for instance getting remote data seeing if it's there then getting back to me. I would have to do it inside the object. – eddyrolo Jan 24 '15 at 20:44
  • Yes. Such a function that checks whether the objects exists is ill-suited *in* the object. Put it outside, and [make your constructor pure](http://stackoverflow.com/q/24398699/1048572). – Bergi Jan 24 '15 at 20:57

4 Answers4

2

if not valid delete the object

Don't. Better, test the email address to be valid before trying to create the user.

or return nothing

You can't really. Returning nothing from a constructor is effectively quite impossible, except you throw an exception.

Use an extra factory function instead:

function isValidEmail(str) {
    // http://davidcel.is/blog/2012/09/06/stop-validating-email-addresses-with-regex/
    return /.+@.+\..+/.test(str);
}
function User(email) {
    // possible, but better don't do this:
    // if (!isValidEmail(email)) throw new Error("Tried to create User with invalid email")
    this.email = email;
}

User.prototype.checkValid = function () {
    return isValidEmail(this.email);
};

User.create = function(email) {
    if (isValidEmail(email))
        return new User(email);
    else
        return null;
};

var user1 = User.create("bob123@aol.com")
if (user1)
    this.checkValid() // true
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Thanks I think this is the best answer to my question. – eddyrolo Jan 24 '15 at 21:06
  • I like the approach, but isn't it a bit overdressed for the occasion? There is still a global var user1, I wouldn't want that. Couldn't you wrap a create function inside an if only returning an instance when valid? – Mouser Jan 24 '15 at 21:09
  • @Mouser: The global `user1` is just for example, you might not do it like this in practise. It depends a lot on what you want to do when the condition is not met, and whether you expect that at all. – Bergi Jan 24 '15 at 21:12
  • I know that user1 is just an example. But in your example when it's not valid you need to delete `user1` from the window object since it's actually `window['user1'] = null`. The code is clear and does it's job perfectly. I've updated mine to reflect the comment I gave. – Mouser Jan 24 '15 at 21:16
  • Well, it's especially examplary that the variable is global… Usually you don't need to clean up variables in functions. – Bergi Jan 24 '15 at 21:22
1

function createUser(username, email)
{
    if (email.match(/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/ig))
    {
        window[username] = new User(email);
        return true;
    }
    else
    {
        return null;
    }
}

function User(email) 
{
    this.email = email;
}

if (createUser("user1", "bob123@aol.com"))
{
    document.write("User 1: " + user1.email + "<br />");        
}
if (createUser("user2", "bob123aol.com"))
{
    document.write("User 2: " + user2.email);
}
document.write(window['user1'] + "<br />");
document.write(window['user2']);

This will check if the user has a valid e-mail. If so create a global variable constructed from User, if not nothing is returned. You can of course replace the window (global scope) object with any other object.

Mouser
  • 13,132
  • 3
  • 28
  • 54
  • So lets say I'm creating a new user var user3 = new User("bob342@aol.com") ... What is the best way to check if it succeeded if (!user3.email) console.log("Invalid Email") or is there a better way. – eddyrolo Jan 24 '15 at 20:29
  • Yes that simple `if` would suffice. You could even incorporate it within the constructor. It could throw an error, or trigger another function showing a message. The script is currently build to do the following: if the email is valid set the property. If not omit the property. – Mouser Jan 24 '15 at 20:35
  • I tried incorporating it in the constructor and it kept returning "undefined" – eddyrolo Jan 24 '15 at 20:40
  • Of course there is an object created even when the email is not valid! – Bergi Jan 24 '15 at 20:44
  • Is there a way to prevent that from happening? – eddyrolo Jan 24 '15 at 20:49
  • Not really. The object is created even before the constructor code is ran. Throwing an exception would prevent the object from being returned from `new`, but I don't think one would want that. – Bergi Jan 24 '15 at 20:53
  • I like your answer @Bergi, but my question is the following: does the OP want the whole user to not exist if an email is invalid or just the email property? – Mouser Jan 24 '15 at 20:55
  • The question sounds like he wants to "*create the object conditionally*" - not only a single property. For that case, your answer would be perfectly valid of course. – Bergi Jan 24 '15 at 20:58
0
function User(email) {
    this.email = email;
    this.check();
};

User.prototype.check = function() {
    if (this.email.match(/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/ig)) {
        console.log('Valid email');
    } else {
        console.log('Invalid email');
    }
};


var user1 = new User("bob123@aol.com");
0

You could use try, catch

function User(email) {
    this.email = email;

    this.checkValid()
}

User.prototype.checkValid = function () {
    var valid = false;
    //or true if valid email

    if(!valid) throw 'Not valid email';
}

try {
    var user1 = new User("bob123@aol.com");
} catch(e) {
    console.log(e);   
}

But in my opinion a constructor should always create an object, so I would do something like this:

function User(email) {
    this.email = email;
}

User.prototype.isValid = function () {
    if (this.email.match(/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/ig)) {
        return true;
    }
    return false;
}

var user1 = new User("bob123@aol.com");

if(!user1.isValid()){
    user1 = null;
}
llernestal
  • 576
  • 2
  • 8