AngularJS promise resolution not updating GUI until next user interaction
I am using an Angular2-style component in AngularJS. In my component, I have a function that is meant to update the GUI by changing the options of a dropdown:
var ctrl = this;
async function updateOptions(node)
var name = node.name;
let result = await MyService.getResult(name);
ctrl.options = result;
console.log(ctrl.options);
The corresponding HTML to display those options is:
<select ng-if="$ctrl.getType() === 'dropdown'"
class="form-control selectList"
ng-model="$ctrl.value"
ng-options="option.key as option.displayName for option in $ctrl.options">
</select>
where getType()
always returns 'dropdown'
.
The dropdown starts blank. The user selects an option from the dropdown. The console logs the options and the dropdown updates correctly. The user selects ANOTHER option from the dropdown. The console logs the options correctly AGAIN. But THIS time, the dropdown does NOT update. All subsequent times, the dropdown shows the options of the PREVIOUS thing the user selected.
Looking forward to some good detective work. Happy to provide more snippets of code from this large project. I'm wondering if this could be an issue with the way that AngularJS updates.
UPDATE:
MyService code:
this.getResult = function(name)
return myFactory.getStuff(name).then(
function(response)
return response.result.map(...);
);
;
MyFactory code:
myFactory.getStuff = function(name)
return $http.get('/url/here/' + name)).then(
function(response)
return response.data;
);
;
javascript angularjs
add a comment |
I am using an Angular2-style component in AngularJS. In my component, I have a function that is meant to update the GUI by changing the options of a dropdown:
var ctrl = this;
async function updateOptions(node)
var name = node.name;
let result = await MyService.getResult(name);
ctrl.options = result;
console.log(ctrl.options);
The corresponding HTML to display those options is:
<select ng-if="$ctrl.getType() === 'dropdown'"
class="form-control selectList"
ng-model="$ctrl.value"
ng-options="option.key as option.displayName for option in $ctrl.options">
</select>
where getType()
always returns 'dropdown'
.
The dropdown starts blank. The user selects an option from the dropdown. The console logs the options and the dropdown updates correctly. The user selects ANOTHER option from the dropdown. The console logs the options correctly AGAIN. But THIS time, the dropdown does NOT update. All subsequent times, the dropdown shows the options of the PREVIOUS thing the user selected.
Looking forward to some good detective work. Happy to provide more snippets of code from this large project. I'm wondering if this could be an issue with the way that AngularJS updates.
UPDATE:
MyService code:
this.getResult = function(name)
return myFactory.getStuff(name).then(
function(response)
return response.result.map(...);
);
;
MyFactory code:
myFactory.getStuff = function(name)
return $http.get('/url/here/' + name)).then(
function(response)
return response.data;
);
;
javascript angularjs
3
AngularJS used promises from the$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.
– Frank Modica
Nov 13 '18 at 14:18
@FrankModica Would it help to post code for thegetResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.
– mareoraft
Nov 13 '18 at 14:26
1
In AngularJS usually people get API results using the built in$http
service, which I believe returns promises which are created from the$q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How isgetResult
implemented? Is it returning a native promise?
– Frank Modica
Nov 13 '18 at 14:29
Using.then
syntax instead ofawait
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.
– mareoraft
Nov 13 '18 at 15:30
To be honest, I'm surprised it worked even once before.await
should work on native promises, but not the ones from$q
!
– Frank Modica
Nov 13 '18 at 15:37
add a comment |
I am using an Angular2-style component in AngularJS. In my component, I have a function that is meant to update the GUI by changing the options of a dropdown:
var ctrl = this;
async function updateOptions(node)
var name = node.name;
let result = await MyService.getResult(name);
ctrl.options = result;
console.log(ctrl.options);
The corresponding HTML to display those options is:
<select ng-if="$ctrl.getType() === 'dropdown'"
class="form-control selectList"
ng-model="$ctrl.value"
ng-options="option.key as option.displayName for option in $ctrl.options">
</select>
where getType()
always returns 'dropdown'
.
The dropdown starts blank. The user selects an option from the dropdown. The console logs the options and the dropdown updates correctly. The user selects ANOTHER option from the dropdown. The console logs the options correctly AGAIN. But THIS time, the dropdown does NOT update. All subsequent times, the dropdown shows the options of the PREVIOUS thing the user selected.
Looking forward to some good detective work. Happy to provide more snippets of code from this large project. I'm wondering if this could be an issue with the way that AngularJS updates.
UPDATE:
MyService code:
this.getResult = function(name)
return myFactory.getStuff(name).then(
function(response)
return response.result.map(...);
);
;
MyFactory code:
myFactory.getStuff = function(name)
return $http.get('/url/here/' + name)).then(
function(response)
return response.data;
);
;
javascript angularjs
I am using an Angular2-style component in AngularJS. In my component, I have a function that is meant to update the GUI by changing the options of a dropdown:
var ctrl = this;
async function updateOptions(node)
var name = node.name;
let result = await MyService.getResult(name);
ctrl.options = result;
console.log(ctrl.options);
The corresponding HTML to display those options is:
<select ng-if="$ctrl.getType() === 'dropdown'"
class="form-control selectList"
ng-model="$ctrl.value"
ng-options="option.key as option.displayName for option in $ctrl.options">
</select>
where getType()
always returns 'dropdown'
.
The dropdown starts blank. The user selects an option from the dropdown. The console logs the options and the dropdown updates correctly. The user selects ANOTHER option from the dropdown. The console logs the options correctly AGAIN. But THIS time, the dropdown does NOT update. All subsequent times, the dropdown shows the options of the PREVIOUS thing the user selected.
Looking forward to some good detective work. Happy to provide more snippets of code from this large project. I'm wondering if this could be an issue with the way that AngularJS updates.
UPDATE:
MyService code:
this.getResult = function(name)
return myFactory.getStuff(name).then(
function(response)
return response.result.map(...);
);
;
MyFactory code:
myFactory.getStuff = function(name)
return $http.get('/url/here/' + name)).then(
function(response)
return response.data;
);
;
javascript angularjs
javascript angularjs
edited Nov 13 '18 at 15:29
mareoraft
asked Nov 13 '18 at 14:17
mareoraftmareoraft
79811027
79811027
3
AngularJS used promises from the$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.
– Frank Modica
Nov 13 '18 at 14:18
@FrankModica Would it help to post code for thegetResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.
– mareoraft
Nov 13 '18 at 14:26
1
In AngularJS usually people get API results using the built in$http
service, which I believe returns promises which are created from the$q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How isgetResult
implemented? Is it returning a native promise?
– Frank Modica
Nov 13 '18 at 14:29
Using.then
syntax instead ofawait
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.
– mareoraft
Nov 13 '18 at 15:30
To be honest, I'm surprised it worked even once before.await
should work on native promises, but not the ones from$q
!
– Frank Modica
Nov 13 '18 at 15:37
add a comment |
3
AngularJS used promises from the$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.
– Frank Modica
Nov 13 '18 at 14:18
@FrankModica Would it help to post code for thegetResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.
– mareoraft
Nov 13 '18 at 14:26
1
In AngularJS usually people get API results using the built in$http
service, which I believe returns promises which are created from the$q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How isgetResult
implemented? Is it returning a native promise?
– Frank Modica
Nov 13 '18 at 14:29
Using.then
syntax instead ofawait
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.
– mareoraft
Nov 13 '18 at 15:30
To be honest, I'm surprised it worked even once before.await
should work on native promises, but not the ones from$q
!
– Frank Modica
Nov 13 '18 at 15:37
3
3
AngularJS used promises from the
$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.– Frank Modica
Nov 13 '18 at 14:18
AngularJS used promises from the
$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.– Frank Modica
Nov 13 '18 at 14:18
@FrankModica Would it help to post code for the
getResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.– mareoraft
Nov 13 '18 at 14:26
@FrankModica Would it help to post code for the
getResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.– mareoraft
Nov 13 '18 at 14:26
1
1
In AngularJS usually people get API results using the built in
$http
service, which I believe returns promises which are created from the $q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How is getResult
implemented? Is it returning a native promise?– Frank Modica
Nov 13 '18 at 14:29
In AngularJS usually people get API results using the built in
$http
service, which I believe returns promises which are created from the $q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How is getResult
implemented? Is it returning a native promise?– Frank Modica
Nov 13 '18 at 14:29
Using
.then
syntax instead of await
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.– mareoraft
Nov 13 '18 at 15:30
Using
.then
syntax instead of await
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.– mareoraft
Nov 13 '18 at 15:30
To be honest, I'm surprised it worked even once before.
await
should work on native promises, but not the ones from $q
!– Frank Modica
Nov 13 '18 at 15:37
To be honest, I'm surprised it worked even once before.
await
should work on native promises, but not the ones from $q
!– Frank Modica
Nov 13 '18 at 15:37
add a comment |
1 Answer
1
active
oldest
votes
await
is meant for native promises which are supported by the browser. You can also use .then
syntax on native promises.
But AngularJS uses its own promises that come from $q
service. Thus you are required to use .then
syntax because the browser doesn't know about these promises.
When you use promises from the $q
service (e.g. when you use $http
) you don't have to worry about digest cycles because a digest is run for you when the promise is fulfilled. But if you use native promises in AngularJS, you usually have to run a digest cycle manually.
The term "digest" does not appear in the AngularJS documentation of$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".
– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that$q
triggers the digest cycle for you when you use its promises.
– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.$apply
and$digest
, for example, are not available. I was able to get certain things to update properly by putting update code within athis.$doChange
function wherethis
is the controller.
– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call$digest
? You probably need to inject$scope
– Frank Modica
Nov 15 '18 at 14:40
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283021%2fangularjs-promise-resolution-not-updating-gui-until-next-user-interaction%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
await
is meant for native promises which are supported by the browser. You can also use .then
syntax on native promises.
But AngularJS uses its own promises that come from $q
service. Thus you are required to use .then
syntax because the browser doesn't know about these promises.
When you use promises from the $q
service (e.g. when you use $http
) you don't have to worry about digest cycles because a digest is run for you when the promise is fulfilled. But if you use native promises in AngularJS, you usually have to run a digest cycle manually.
The term "digest" does not appear in the AngularJS documentation of$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".
– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that$q
triggers the digest cycle for you when you use its promises.
– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.$apply
and$digest
, for example, are not available. I was able to get certain things to update properly by putting update code within athis.$doChange
function wherethis
is the controller.
– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call$digest
? You probably need to inject$scope
– Frank Modica
Nov 15 '18 at 14:40
add a comment |
await
is meant for native promises which are supported by the browser. You can also use .then
syntax on native promises.
But AngularJS uses its own promises that come from $q
service. Thus you are required to use .then
syntax because the browser doesn't know about these promises.
When you use promises from the $q
service (e.g. when you use $http
) you don't have to worry about digest cycles because a digest is run for you when the promise is fulfilled. But if you use native promises in AngularJS, you usually have to run a digest cycle manually.
The term "digest" does not appear in the AngularJS documentation of$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".
– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that$q
triggers the digest cycle for you when you use its promises.
– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.$apply
and$digest
, for example, are not available. I was able to get certain things to update properly by putting update code within athis.$doChange
function wherethis
is the controller.
– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call$digest
? You probably need to inject$scope
– Frank Modica
Nov 15 '18 at 14:40
add a comment |
await
is meant for native promises which are supported by the browser. You can also use .then
syntax on native promises.
But AngularJS uses its own promises that come from $q
service. Thus you are required to use .then
syntax because the browser doesn't know about these promises.
When you use promises from the $q
service (e.g. when you use $http
) you don't have to worry about digest cycles because a digest is run for you when the promise is fulfilled. But if you use native promises in AngularJS, you usually have to run a digest cycle manually.
await
is meant for native promises which are supported by the browser. You can also use .then
syntax on native promises.
But AngularJS uses its own promises that come from $q
service. Thus you are required to use .then
syntax because the browser doesn't know about these promises.
When you use promises from the $q
service (e.g. when you use $http
) you don't have to worry about digest cycles because a digest is run for you when the promise is fulfilled. But if you use native promises in AngularJS, you usually have to run a digest cycle manually.
answered Nov 13 '18 at 15:44
Frank ModicaFrank Modica
6,4442727
6,4442727
The term "digest" does not appear in the AngularJS documentation of$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".
– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that$q
triggers the digest cycle for you when you use its promises.
– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.$apply
and$digest
, for example, are not available. I was able to get certain things to update properly by putting update code within athis.$doChange
function wherethis
is the controller.
– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call$digest
? You probably need to inject$scope
– Frank Modica
Nov 15 '18 at 14:40
add a comment |
The term "digest" does not appear in the AngularJS documentation of$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".
– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that$q
triggers the digest cycle for you when you use its promises.
– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.$apply
and$digest
, for example, are not available. I was able to get certain things to update properly by putting update code within athis.$doChange
function wherethis
is the controller.
– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call$digest
? You probably need to inject$scope
– Frank Modica
Nov 15 '18 at 14:40
The term "digest" does not appear in the AngularJS documentation of
$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".– mareoraft
Nov 13 '18 at 16:23
The term "digest" does not appear in the AngularJS documentation of
$q
. Perhaps you could provide a link to a good resource that explains how/when angular "digests".– mareoraft
Nov 13 '18 at 16:23
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that
$q
triggers the digest cycle for you when you use its promises.– Frank Modica
Nov 13 '18 at 16:32
The digest cycle is a fundamental concept in AngularJS (it's how the framework accomplishes change detection). AngularJS has been out for so long that a google search would get you a ton of quality explanations. Once you understand the digest cycle, you really just need to know that
$q
triggers the digest cycle for you when you use its promises.– Frank Modica
Nov 13 '18 at 16:32
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.
$apply
and $digest
, for example, are not available. I was able to get certain things to update properly by putting update code within a this.$doChange
function where this
is the controller.– mareoraft
Nov 15 '18 at 14:37
I'm not sure if there is a way to manually run a digest cycle when using Angular2-style components in AngularJS.
$apply
and $digest
, for example, are not available. I was able to get certain things to update properly by putting update code within a this.$doChange
function where this
is the controller.– mareoraft
Nov 15 '18 at 14:37
On what object did you try to call
$digest
? You probably need to inject $scope
– Frank Modica
Nov 15 '18 at 14:40
On what object did you try to call
$digest
? You probably need to inject $scope
– Frank Modica
Nov 15 '18 at 14:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283021%2fangularjs-promise-resolution-not-updating-gui-until-next-user-interaction%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
AngularJS used promises from the
$q
service which would run a digest for you. If you are using native promises, I think you need to run a digest manually.– Frank Modica
Nov 13 '18 at 14:18
@FrankModica Would it help to post code for the
getResult
method? Unfortunately I am not familiar with the $q service, but I'll read up on it now.– mareoraft
Nov 13 '18 at 14:26
1
In AngularJS usually people get API results using the built in
$http
service, which I believe returns promises which are created from the$q
service. Thus a digest cycle is automatically run for you when the AJAX response is received. How isgetResult
implemented? Is it returning a native promise?– Frank Modica
Nov 13 '18 at 14:29
Using
.then
syntax instead ofawait
seems to be working. But for the sake of completeness, I have still included requested details above. Perhaps you can post a brief answer below explaining why this works. Thanks kindly for your help.– mareoraft
Nov 13 '18 at 15:30
To be honest, I'm surprised it worked even once before.
await
should work on native promises, but not the ones from$q
!– Frank Modica
Nov 13 '18 at 15:37