1
\$\begingroup\$

I've been given the task to create a micro-service which basically logs in OR creates a user. I chose to do this with express.js and node (which now supports es6 functionality). My code feels a bit messy and I'm not 100% sure it's the most object oriented, can I make it better?

I've got 4 files:

  1. handlers/login_register.js
  2. classes/login.js
  3. classes/facebook.js
  4. classes/email.js (this is not yet implemented but extends of login.js (like facebook.js)

The handler/login_register will basically initiate a new login type (facebook.js or email.js).

class LoginRegister {
  constructor(req, res) {
    this.req = req;
    this.res = res;
    this.User = null;
    this.foundUserId = null;
    this.fbPermissions = ['email', 'id', 'name', 'about', 'hometown', 'cover', 'picture'];
    this.clientFbToken = req.body.fb_token ? req.body.fb_token : null;
    if (this.clientFbToken) this.User = new Facebook(this.fbPermissions, this.clientFbToken);
    else this.User = new Email(this.username, this.password); // Not yet implemented
    // Change object to Email
    this.main();
  }

  main () {
    this.User.main()
    .then ( (createNew) => {
      console.log ("SHould create new user", createNew)
      // Create a new user
      if (createNew) {
        this.User.createUser()
        .then (()=> this.User.createUserDetails())
        .then(()=>this.returnToken())
        .catch ((err) => console.log ("error", err))
      } else {
        console.log ("Return new token for", this.User.User);
        this.User.createUserDetails()
        this.returnToken();
        // this.res.json(JSON.stringify(this.User.User));
      }

      // this.User.checkUserExist (true, thi)
    }).catch((err) => console.log ("err loginregister", err))
  }

  returnToken () {
    console.log ("user has been created/fond and returning a token", this.User);
    this.res.json(JSON.stringify({token: "TOKEN MUTHERFUCKEREREKREKRKEKRKERKEKREKRKEKRRE", user: this.User}));
  }
}

The classes/login.js basically has two methods which both the, facebook, and email classes will inherit.

class Login {
  constructor() {
    this.user_id = null;
    this.foundUser = {};
    this.User = {};
  }

  /**
    @params {bool} isFb, if using facebook class, use a different select stmt
    @param {object OR string} can either be object or a stringfbId or username + password
  **/
  checkUserExists (isFb, data) {
    var query;
    if (isFb) {
      query = `select * from content_user where fbId = ${data}`;
    } else {
      query = `select * from content_user where email = ${data.email} AND password = ${data.password}`;
    }
    const that = this;

    return new Promise ( (fulfill, rej) => {
      conn.query(query, function (err, user) {
        if (err) {
          console.log ("\nSomething went wrong: ", err);
          rej(err);
          return;
        }
        const shouldCreate = user.length > 0 ? false : true;
        if (!shouldCreate) that.user_id = user[0].id;

        console.log (shouldCreate, ", should create new user")
        fulfill(shouldCreate);
      })
    });
  }

  createUser () {
    var User = new UserModel(this.User);
    var q;

    // Temp till I fix django default
    var date;
    date = new Date();
    date = date.getUTCFullYear() + '-' +
        ('00' + (date.getUTCMonth()+1)).slice(-2) + '-' +
        ('00' + date.getUTCDate()).slice(-2) + ' ' +
        ('00' + date.getUTCHours()).slice(-2) + ':' +
        ('00' + date.getUTCMinutes()).slice(-2) + ':' +
        ('00' + date.getUTCSeconds()).slice(-2);
    if (this.fbId){
      q = `INSERT INTO content_user SET fbId = ${this.fbId}, created = '${date}'`;
    } else {
      q = `INSERT INTO content_user set created = ${new Date()}`;
    }
    var that = this;
    // Set fbId to the new user entity
    return new Promise ( (ful, rej) => {
      conn.query(q , function(err, result) {
        if (err) {
          console.log ("ERROR", err)
          rej(err);
          return;
        }
        that.user_id = result.insertId;

        // Return token for id here...
        ful(result.insertId);

      });
    });
  }

  createUserDetails () {
    var User = new UserDataModel(this.User, this.user_id);
    var q;

    // Temp till I fix django default
    var date;
    date = new Date();
    date = date.getUTCFullYear() + '-' +
        ('00' + (date.getUTCMonth()+1)).slice(-2) + '-' +
        ('00' + date.getUTCDate()).slice(-2) + ' ' +
        ('00' + date.getUTCHours()).slice(-2) + ':' +
        ('00' + date.getUTCMinutes()).slice(-2) + ':' +
        ('00' + date.getUTCSeconds()).slice(-2);

    // Set fbId to the new user entity
    return new Promise ( (ful, rej) => {
      conn.query(`INSERT INTO content_userdata SET ? `, User, function(err, result) {
        if (err) {
          console.log ("ERROR", err)
          rej(err);
          return;
        }


        ful(result.insertId);
      });
    });
  }

  // Add insert here ...
}

The classes/facebook.js extends login.js and basically calls the facebook api, receives a chunk of data, and normalises it.

class Facebook extends Login {
  constructor(fbPermissions, fbToken) {
    super();
    this.fbPermissions = fbPermissions;
    this.fbToken = fbToken;
    this.fbUser = {};
    this.fbId = null;
    this.foundUser = {};
  }

  main () {
    // This just grabs facebook /me data
    return new Promise( (fullfil, rej) => {
       grabMeData (this.fbPermissions, this.fbToken)
      .then ( (fbData) => {
        const fb = new FbUser(fbData);
        this.User = new User (fb); // Set UserDetails model up | Which will be used to insert user
        this.fbId = fb.fbId;
        this.checkUserExists(true, this.User.fbId).then((isCreated)=>fullfil(isCreated)).catch((err)=>console.log(err))
      })
      .catch ( (err) => {
        this.error = err;
        console.log (err, "<~~ ERROR")
        rej();
      });
    });
  }
}

module.exports = Facebook;

I haven't done much OOP, and am aware that javascript is not the best for doing it, and I'm just wanting to know if I can clean up my code to make it more object oriented?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.