0

I have a big problem with Javascript (I'm developing a web application with Angular 4 using TypeScript language. Backend side is developed using AWS). I don't know how to use the asynchronous call mechanism very well.

Unfortunately if I using promises I can not use any object in the code.

I wish manipulate them in my methods. But the only thing I can do is use this data for a static display in the html template, and don't manipulate them in the code. This is an example of my code:

// In ClassA
  getCognitoUsers() {

  var params = {
    UserPoolId: environment.userPoolId
  };

  return this.cognitoIdentityServiceProvider.listUsers(params).promise();

}

 // In ClassB
        let container = this;
        this.ClassB.getCognitoUsers().then(
        function(data) {
           container.myProperty = data;
        }
    );

The object this.myProperty it can also be refered by other classes in the application. The problem is that I can do what I want in the html template, but not in the business code, such this:

// In the HTML template
{{myProperty.mySubProperty}} <!-- displays correctly! -->
// In the .ts file
myMethod() {
 let subProperty = this.myProperty.mySubProperty; // ERROR: will always be undefined because not in asynchronous flow
}

I know that the problem is this because I called an asynchronous method, but I hoped that with the promises I would have resolved the situation. Someone can tell me what's wrong in this code and how can I get the object to manipulate in the business code (and not only statically in the template)? I would like some important operations of the application to be performed AFTER the asynchronous call!

claudioz
  • 1,121
  • 4
  • 14
  • 25
  • Side note: No need for that `container` variable in ClassB. Just use an arrow function: `this.ClassB.getCognitoUsers().then(data => { this.myProperty = data; });` Side note 2: **Always** handle promise rejections or return the promise to the caller to handle them. – T.J. Crowder Sep 26 '17 at 12:14
  • You yourself understood the problem, you have to call the myMethod() inside "then" callback. – omeralper Sep 26 '17 at 12:15
  • We can't help you without more information. Fundamentally you're trying to use the value before you have it. So you need to wait until you have it. That probably means returning the promise and having the next step wait on its resolution, but... – T.J. Crowder Sep 26 '17 at 12:15
  • You can use async and await in your code for making this synchronous call. – Pulkit Aggarwal Sep 26 '17 at 12:16
  • @PulkitAggarwal can you give me an example? What I want is to wait for the data to arrive, then invoke the methods on them! – claudioz Sep 26 '17 at 12:20
  • @T.J.Crowder How do I wait for the data to be returned without performing any operations? – claudioz Sep 26 '17 at 12:28
  • By effective use of promises (or just callbacks) and/or guard conditions (checking to make sure `this.myProperty` exists before trying to use `mySubProperty` on it), depending on which is appropriate (they both are at different times). – T.J. Crowder Sep 26 '17 at 12:34
  • You can add 'async' before getCognitoUsers function and add 'await' before the statement where you call this function i.e this.ClassB.getCognitoUsers() – Pulkit Aggarwal Sep 26 '17 at 12:38
  • The 'await' keyword before the statement this.ClassB.getCognitoUsers() give me an error: 'Cannot find name 'await'.' – claudioz Sep 26 '17 at 12:59

0 Answers0