Farhan Islam
Farhan Islam

Reputation: 649

How to resolve chained promise between services in Angular?

I have a dynamo db service in my Angular project that returns a promise through a chain of promises which gets a subId from cognito which thens passes that subId to a dyamodb get query:

async getUserObject(): Promise<any> {
    var promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            let response; 
            let cognitoUser = this.cognitoUtil.getCurrentUser();
            cognitoUser.getSession(function (err, session) {
            if (err)
                console.log("UserParametersService: Couldn't retrieve the user");
            else {
                //Here were grabbing the subId and returning a promise 
                cognitoUser.getUserAttributes(
                    function getSubId(err, result) {
                        let cognitoSubIdPromise = new Promise((resolve,reject) => {
                            setTimeout(() => {
                                if (err) {
                                    reject('error');
                                } else {
                                    let response: any = result[0].getValue();
                                    resolve(response);
                                }
                            }, 1000);
                        });
                        //Once we've resolved the subId from Cognito we can plug it into our dynamodb query
                        cognitoSubIdPromise.then((val) => {
                            let clientParams:any = {
                                params: {TableName: environment.ddbTableName}
                            };
                            if (environment.dynamodb_endpoint) {
                                clientParams.endpoint = environment.dynamodb_endpoint;
                            }
                            var DDB = new DynamoDB(clientParams);
                            var getParams = {
                                TableName: environment.ddbTableName,
                                Key: {
                                    'userId' : {S: val.toString()},
                                }
                            };
                            //Here we are executing the query
                            DDB.getItem(getParams, 
                                function (err, result) {
                                    if (err){
                                        console.log(err)
                                    } else {
                                        console.log("DynamoDBService got user object: " + JSON.stringify(result));
                                        response = result;
                                    }
                                }
                            );
                        });
                    });
                }
            });
          console.log("Async Work Complete");
          resolve(response);
        }, 1000);
      });
      return promise;
}

In the other user-login service, I am trying to make sure that a Cognito function callback which takes us to the home page of the app after login is only executed once the db query is complete from my dynamo db service

databaseDynamo.getUserObject().then((data => {
                console.log("this is the resolved data", data);
                console.log("getUserObject function execution done!");
                callback.cognitoCallback(null, session);
           }));

This console log of resolved data always returns as undefined, and the cognito callback function executes before the resolved data has a value. How do I make sure that the cognitoCallBack function is not triggered until I have a value for data?

Upvotes: 1

Views: 152

Answers (1)

Joy Biswas
Joy Biswas

Reputation: 6527

This is because you are resolving out of place

async getUserObject(): Promise < any > {
  var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      let response;
      let cognitoUser = this.cognitoUtil.getCurrentUser();
      cognitoUser.getSession(function (err, session) {
        if (err)
          console.log("UserParametersService: Couldn't retrieve the user");
        else {
          //Here were grabbing the subId and returning a promise 
          cognitoUser.getUserAttributes(
            function getSubId(err, result) {
              let promise = new Promise((resolve, reject) => {
                setTimeout(() => {
                  if (err) {
                    reject('error');
                  } else {
                    let response: any = result[0].getValue();
                    resolve(response);
                  }
                }, 1000);
              });
              //Once we've resolved the subId from Cognito we can plug it into our dynamodb query
              promise.then((val) => {
                let clientParams: any = {
                  params: { TableName: environment.ddbTableName }
                };
                if (environment.dynamodb_endpoint) {
                  clientParams.endpoint = environment.dynamodb_endpoint;
                }
                var DDB = new DynamoDB(clientParams);
                var getParams = {
                  TableName: environment.ddbTableName,
                  Key: {
                    'userId': { S: val.toString() },
                  }
                };
                //Here we are executing the query
                DDB.getItem(getParams,
                  function (err, result) {
                    if (err) {
                      console.log(err)
                      reject(err);//added reject in case of any error
                    } else {
                      console.log("DynamoDBService got user object: " + JSON.stringify(result));
                      response = result;
                      resolve(response); // <--- added resolve to here
                    }
                  }
                );
              }); // you should have a error handler here in case the inner promise is rejected
            });
        }
      });
      console.log("Async Work Complete");
      // <------ removed resolve from here
    }, 1000);
  });
  return promise;
}

You should check your variable names it is confusing maybe name it inner promise innerresolve or something, but it shouldn't matter. I think moving the resolve should fix it.

Upvotes: 1

Related Questions