0

I am calling class using following code

var user_ctx = new user();
user_ctx
    .set_email(req.body.email)
    .then(user_ctx.set_username(req.body.username))
    .catch((err)=>{
        console.log(err);
    });

and the class is defined as follows

function user () {
    this.user = {};
};

user.prototype.set_username = function (username) {
    return new Promise((fullfill,reject)=>{
        this.user.username = username;
        fullfill();
    });
};

user.prototype.set_email = function (email) {
    return new Promise((fullfill,reject)=>{
        var email_ctx = new email_lib(email);
        email_ctx
            .is_valid()
            .then(function() {
                this.user.email = email;
            })
            .then(fullfill)
            .catch(reject);
    });
};

the problem is that the email us not defined in user. i also tried the following

user.prototype.set_email = function (email) {
    return new Promise((fullfill,reject)=>{
        var email_ctx = new email_lib(email);
        var that = this;
        email_ctx
            .is_valid()
            .then(function() {
                that.user.email = email;
            })
            .then(fullfill)
            .catch(reject);
    });
};

thereby referencing it using that inside callback function; but the email is still not being set. Already tried logging that the variable email is there in promise chain of set_email where am i going wrong with this ?

alexmac
  • 19,087
  • 7
  • 58
  • 69
georoot
  • 3,557
  • 1
  • 30
  • 59
  • 2
    `return new Promise((fullfill,reject)=>{ this.user.username = username; });` - this is a promise that will never be anything but a pending Promise - this has no value whatsoever – Jaromanda X Aug 19 '17 at 07:21
  • @JaromandaX i forgot to add that `fullfill()` code to that block just to keep code short and to the point. the problem is with setting the value of email in `this.user` the setting of `username` is working fine which i verified by writing another method to print out the contents of same – georoot Aug 19 '17 at 07:25
  • well, you're also guilty of the classic promise anti-patterns - https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – Jaromanda X Aug 19 '17 at 07:29
  • 1
    `.then(function() { this.user.email = email; })` check what `this` is in this code – Jaromanda X Aug 19 '17 at 07:30
  • @JaromandaX its coming out to be undefined; – georoot Aug 19 '17 at 07:33
  • i usually go with `set_email.bind(this)` but the method in this case needs to take params with it – georoot Aug 19 '17 at 07:33
  • 2
    use an arrow function – Jaromanda X Aug 19 '17 at 07:45
  • Tried with arrow functions. Logging the output in next line inside the function gives proper result. but when i later print the object it does not print the whole object. – georoot Aug 19 '17 at 07:56

1 Answers1

1

Your code doesn't work as expected, due to several errors / incorrect implementation:

  1. You call user_ctx.set_username immediately, without waiting the promise will be resolved. Instead of .then(user_ctx.set_username(req.body.username)) you must use: .then(() => user_ctx.set_username(req.body.username)).
  2. You create Promise via constructor, when calling service email_ctx is already returns a promise.
  3. You use wrong this. Inside the function this points to the parent function.

Correct implementation might look like this:

var user_ctx = new user();
user_ctx
    .set_email(req.body.email)
    .then(() => user_ctx.set_username(req.body.username))
    .catch(err => console.log(err));

function user () {
    this.user = {};
};

user.prototype.set_email = function(email) {
    var self = this;
    var email_ctx = new email_lib(email);
    return email_ctx
        .is_valid()
        .then(function() {
           self.user.email = email;
        });
    });
};

user.prototype.set_username = function (username) {
    this.user.username = username;
};
alexmac
  • 19,087
  • 7
  • 58
  • 69