Angular2, view not updating after variable changes in settimeout
Solution 1
As Vlado said, it should work ;-)
I think that the angular2-polyfills.js
library should be included into your page. I can't see it. This file is essentially a mashup of zone.js and reflect-metadata. Zones take part of the detection of updates.
You could have a look at this video where Bryan Ford explains what it is: https://www.youtube.com/watch?v=3IqtmUscE_U.
Hope it helps you, Thierry
Solution 2
That should work. Do you have any other errors in console?
@Component({
selector: 'my-app',
template: `<h1>Hello {{title}}</h1>`
})
export class App {
public title: string = "World";
constructor() {
setTimeout(() => {
this.title = "Brave New World"
}, 1000);)
}
}
Look at this Plunker: http://plnkr.co/edit/XaL4GoqFd9aisOYIhuXq?p=preview
Solution 3
I had a very similar problem to the OP where even in a basic Angular2 setup changes to bound properties would not be reflected by the view automatically. At this point in time we're using Angular2 2.0.0-rc.6. There was no error message.
In the end I found the culprit to be a reference to es6-promise.js, which was 'required' by a third party component we use. Somehow this interfered with the core-js reference we are using which is suggested with rc6 in some of the Angular2 tutorials.
As soon as I got rid of the es6-promise.js reference, the view updated correctly after changing a property on my component (via Promise or timeout).
Hope this helps somebody some day.
Solution 4
In Angular2 (~2.1.2) another way to make it work is through the ChangeDetectorRef class. The original question code would look like this:
import {
ChangeDetectorRef
// ... other imports here
} from '@angular/core';
@Component({
selector: "my-app",
bindings: []
})
@View({
templateUrl: "templates/main.component.html",
styleUrls: ['styles/out/components/main.component.css']
})
export class MainComponent {
public test2 = "initial text";
constructor(private cd: ChangeDetectorRef) {
setTimeout(() => {
this.test2 = "updated text";
// as stated by the angular team: the following is required, otherwise the view will not be updated
this.cd.markForCheck();
}, 500);
}
}
Related videos on Youtube
Jurgen Welschen
Updated on July 17, 2022Comments
-
Jurgen Welschen almost 2 years
I am trying to setup my first angular2 application as an experiment and am using the latest beta release.
I am facing a weird issue where the variable i am using in my view is not being updated after setting a timeout.
@Component({ selector: "my-app", bindings: [] }) @View({ templateUrl: "templates/main.component.html", styleUrls: ['styles/out/components/main.component.css'] }) export class MainComponent { public test2 = "initial text"; constructor() { setTimeout(() => { this.test2 = "updated text"; }, 500); } }
As you can see i have a variable named test2 and in the constructor i set a timeout of 500 ms where i am updating the value to "updated text".
Then in my view main.component.html i simply use:
{{ test2 }}
But the value will never be set to "updated text" and stays on "initial text" forever even though the update part is being hit. If i follow the angular2 tutorial they dont really give me an answer to this solution. Was wondering if anyone would have an idea of what i am missing here.
edit: my full code i am using including the bootstrap and html etc
<html> <head> <title>Angular 2</title> <script src="/node_modules/systemjs/dist/system.src.js"></script> <script src="/node_modules/reflect-metadata/reflect.js"></script> <script src="/node_modules/angular2/bundles/angular2.dev.js"></script> <script src="/node_modules/q/q.js"></script> <script src="/node_modules/jquery/dist/jquery.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="/bower_components/breeze-client/breeze.debug.js"></script> <script src="/bower_components/datajs/datajs.js"></script> <script src="/bower_components/bootstrap-less/js/collapse.js"></script> <script src="/bower_components/bootstrap-less/js/modal.js"></script> <script src="/bower_components/signalr/jquery.signalR.js"></script> <script src="http://localhost:64371/signalr/js"></script> <link href="styles/out/main.css" type="text/css" rel="stylesheet" /> <script> System.config({ map: { rxjs: '/node_modules/rxjs' // added this map section }, packages: {'scripts/out': {defaultExtension: 'js'}, 'rxjs': {defaultExtension: 'js'}} }); System.import('scripts/out/main'); </script> </head> <body> <my-app>loading...</my-app> </body> </html>
main.ts with the bootstrap:
import {Component} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser' import {COMMON_DIRECTIVES} from './constants'; import {MainComponent} from './components/main.component' bootstrap(MainComponent);
main-component.html
{{ test2 }}
-
Poul Kruijt over 8 yearsI've just rebuild your minimal angular2 app, but i do get the updated text result. Is there any error in the console? If not, can you give more code? Like your
index.html
,main.component.html
and where you bootstrap the app
-
-
Jurgen Welschen over 8 yearsThank you, no errors in the console. I have updated my question with the full code, i notice you are using import 'rxjs/Rx'; and i am not. I could not see this in the tutorial. Is there a reason you do it like this?
-
Jurgen Welschen over 8 yearsThat was it! But i dont understand. i used to develop with the alpha some versions back and this would work out of the box. How come they dont include this in the angular2 package by default?
-
Thierry Templier over 8 yearsYes, agreed! There are some differences between alpha versions and the beta one... Things that worked before and can now not work anymore. That's the problem when you're in alpha. Otherwise I guess that they don't put this into angular2 package because it's not actually angular2 ;-) My two cents
-
Vlado Tesanovic over 8 yearsNo no, you don't need it, i forked my other plunker and it left... :( As Thierry said, just include angular2-polyfills.min.js in your index.html
-
Motassem Kassab over 7 yearsthis totally worked for me with angular 2.0, thanks.