Reputation: 1627
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
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)
});
}
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