I have a controller which calls a service, the service does an async work, when the work (Promise
) is done I set a property on the controller's scope object.
function TodoController(TodosService) {
let self = this;
TodosService.fetchTodos().then((todos) => (self.todos = todos));
... other code here
}
The problem is that using async/await in the service does not update the html rendered elements after the promise is resolved, but using then
works normally and updates the rendered elements with the fetched todos:
app.service("TodosService", function ($http) {
// This code does not work, it fetches the todos successfully and also the controller succesfully sets them as a property, but no visual change happens
// this.fetchTodos = async function () {
// let json = await $http.get("...");
// return json.data["todos"];
// };
// This code works normally as explained above
this.fetchTodos = () =>
$http
.get("...")
.then((json) => json.data["todos"]);
}
What is the difference between the two cases, because AFAIK (I'm new to JS) both an async
function and $http.get(...).then(...)
will return promises, so what am I missing here?
CodePudding user response:
await
~wraps you code into native Promise and put later code into callback.
$http
runs http request and then triggers $digest
So line TodosService.fetchTodos().then((todos) => (self.todos = todos));
when u use await will:
- run http request
- run digest
- change controller
todos
field
And as u see digest will not see your changes.
P.S. Things can be a bit more complicated as $http
may trigger async digest (when useApplyAsync
is set to true) and then this code may actually work with await
sometimes(?) but is unreliable anyway.