bbusdriver
bbusdriver

Reputation: 1627

Getting value after clicking twice

I have a lack of understanding asynchronous operation while I'm dealing with a promise function in angular. So basically, I'm trying to get a value from a promise method and assign it to a global variable in a component. However, the value appears to be undefined in the console when I click a button once, and it starts to show the value after clicking it once more.

Html:

<button type="submit" (click)="loadInfo(form)">Submit</button>

Service:

@Injectable()
export class Web3Service {
    constructor...

    getInfo(address: string): Promise<any> {
        return this.TestBetting.deployed().then((instance) => {
          return instance.getInfo.call(address);
        })
        .then((value) => {
          var serialized = this.itemsService.getSerialized<IGetInfo>(value); 
          return this.mappingService.mapValueToGetInfo(serialized); 
        })
        .catch((e) => {
          console.log(e);
        });
    }  
}

Component:

export class HomeComponent {
    infoMapped: any;

    constructor(private web3Service: Web3Service) {}

    loadInfo(): void {
        var test = this.web3Service.getInfo(this.address); 
        test.then((value) => {
            this.infoMapped = value;
        })
        console.log(this.infoMapped)
    }
}

What needs to be fixed so that infoMapped value can be shown in the console after clicking the button only once?

Upvotes: 0

Views: 180

Answers (1)

acdcjunior
acdcjunior

Reputation: 135802

This part:

loadInfo(): void {
    var test = this.web3Service.getInfo(this.address); 
    test.then((value) => {
        this.infoMapped = value;
    })
    console.log(this.infoMapped)
}

What needs to be fixed so that infoMapped value can be shown in the console after clicking the button only once?

To get that, move the console.log(this.infoMapped) into the promise:

loadInfo(): void {
    var test = this.web3Service.getInfo(this.address); 
    test.then((value) => {
        this.infoMapped = value;
        console.log(this.infoMapped)
    });
}

Reasoning

This will fix because the function at test.then(<THIS FUNCTION HERE>) is not executed right away, but only when the Promise object that test holds (that was returned by getInfo()) resolves.

And it will take a bit of time for it to resolve. Millisseconds, maybe, but still won't execute right away.

It won't execute, but the code still goes on. When it goes on, it executes the console.log(this.infoMapped) right away.

Now, because the test.then(<THIS FUNCTION HERE>) hadn't executed yet (remember: it doesn't execute right away, but some time in the near future), its code (the assignment this.infoMapped = value;) has not yet been executed when the console.log(this.infoMapped) runs.

That's why you log undefined the first time.

Now, by the second time you click, the first test.then(<THIS FUNCTION HERE>) of the first click has had enough time to execute. And now the console.log(this.infoMapped) will print the value that was updated when it ran.

(Also notice the test.then(<THIS FUNCTION HERE>) will execute again in the future, due to the second click, yet assigning another value - maybe identical - to this.infoMapped).

Upvotes: 1

Related Questions