0

I currently have two promises, whereas the child is dependent on the parents success. I want to Resolve/reject the parent promise from the child promises "then".

const UserApplicaiton = require('../applications/user'), User = new UserApplicaiton();          

class CheckParams {
    constructor() { }

    required(params, required_params) {
        return new Promise(function(resolve, reject, onCancel) {
            // set i
            var i;

            // set missed_required_params
            var missed_required_params = [];

            // check for userCredentials if user_id is required param, convert from credentials to user_id
            if(required_params.includes("user_id")){
                // set as const
                const user_key = String(params.userCredentials.user_key);
                const user_secret = String(params.userCredentials.user_secret);

                // check in database
                User.info(user_key, user_secret).then((data) => {
                    // if data
                    if(data) {
                        // add user_id to params
                        params.user_id = data[0]._id;

                        // loop params
                        for(i = 0; i < required_params.length; i++){
                            // if params that's required is there, else add to array
                            if(!(required_params[i] in params)){
                                missed_required_params.push(required_params[i]);
                            }
                        }

                        if(missed_required_params.length !== 0){
                            reject("Missed parameters: " + missed_required_params);
                        }else{
                            resolve(params);
                        }
                    }
                }).catch((err) => {
                    reject(err);
                });
            }else{
                // loop params
                for(i = 0; i < required_params.length; i++){
                    // if params that's required is there, else add to array
                    if(!(required_params[i] in params)){
                        missed_required_params.push(required_params[i]);
                    }
                }

                if(missed_required_params.length !== 0){
                    console.log("hello");
                    return reject("Missed parameters: " + missed_required_params);
                }else{
                    console.log("hello2");
                    resolve(1);
                }
            }
        });
    }
}

module.exports = CheckParams;

The goal for the second promise is to add to an object based on the response, and then resolve the parent promise, which will be used later in the code.

This doesn't work at all. Async doesn't really help.

sfsefsf33fs3fs3fs
  • 543
  • 3
  • 6
  • 17
  • what doesn't work? do you call resolve in after `// fetch from database` – gp. May 12 '19 at 12:04
  • The resolve doesn't resolve the parent Promise. I call on the resolve under `// but that doesn't work`, which will make this run until cURL (using express) terminates. My goal is to resolve the parent promise in this state @gp. – sfsefsf33fs3fs3fs May 12 '19 at 12:07
  • You should call `resolve()` or better something like `resolve(obj)`, not `resolve(resolve)`. Your outer `then` callback expects a `data` parameter, so you should fulfill your promise accordingly. – Bergi May 12 '19 at 12:10
  • @Bergi this doesn't work for the parent promise sadly – sfsefsf33fs3fs3fs May 12 '19 at 12:12
  • Also avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! The outer `new Promise` is unnecessary, you [should do conditionals without it](https://stackoverflow.com/a/26600424/1048572). – Bergi May 12 '19 at 12:12
  • @sfsefsf33fs3fs3fs how so? What else happens? Are you sure that `resolve` is in scope? Are you getting any exceptions/rejections? – Bergi May 12 '19 at 12:13
  • @Bergi the reason I know it's not working is the cURL never closes. When I add resolve() above child Promise it works, so maybe it's not in scope but not sure how I solve this – sfsefsf33fs3fs3fs May 12 '19 at 12:19
  • @sfsefsf33fs3fs3fs You might want to post your full, complete code without any omissions. – Bergi May 12 '19 at 12:26
  • This is about what there is @Bergi due to me breaking down stuff – sfsefsf33fs3fs3fs May 12 '19 at 12:43
  • @Bergi thinking about the Resolve not being in scope, but how may I pass it through? – sfsefsf33fs3fs3fs May 12 '19 at 12:48
  • Please post a [mcve]. What are "do some stuff" and "fetch from database"? Where do `userDetails`, `obj`, `dbData` come from? I cannot reproduce your issue. – Bergi May 12 '19 at 12:49
  • @sfsefsf33fs3fs3fs `resolve` *is* in scope in the code you posted, but maybe you are doing weird stuff in the code that you didn't post. – Bergi May 12 '19 at 12:50
  • @Bergi updated with old code before I tried to break it down – sfsefsf33fs3fs3fs May 12 '19 at 12:55

1 Answers1

1

Your problem appears to be that if(data) { is missing an else clause where you would settle the promise as well. Avoiding the Promise constructor antipattern helps to avoid such mistakes as well.

required(params, required_params) {
    var promise;
    if (required_params.includes("user_id")) {
        const user_key = String(params.userCredentials.user_key);
        const user_secret = String(params.userCredentials.user_secret);

        promise = User.info(user_key, user_secret).then((data) => {
            if (data) {
                params.user_id = data[0]._id;
            }
            // else
            //    throw error? keep user_id undefined?
        })
    } else {
        promise = Promise.resolve();
    }
    return promise.then(() => {
        var missed_required_params = [];
        for (var i = 0; i < required_params.length; i++) {
            if (!(required_params[i] in params)) {
                missed_required_params.push(required_params[i]);
            }
        }
        if (missed_required_params.length !== 0) {
            throw new Error("Missed parameters: " + missed_required_params);
        } else {
            return params;
        }
    });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks, the problem is that I need the "params" data later on. When I try to fetch this (`var paramData = CheckParams.required(req.body, requiredParams)`) it returns `Promise { }`, and it cannot be used, so therefore I used a promise at top and needed to resolve the parent. Do you have any ideas on how I can fix this? What I though was: `CheckParams.required(req.body, requiredParams).then((data) => {` and then to the whole thing inside where I can use "data" – sfsefsf33fs3fs3fs May 12 '19 at 13:18
  • Yes, the `required` method is asynchronous so it always has to return a promise (like the code in my answer does - you don't need `new Promise` for that). Indeed, you have to use that with `.then()` at the calling site. – Bergi May 12 '19 at 13:34