Angular2, view not updating after variable changes in settimeout

26,416

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);
    }
}
Share:
26,416

Related videos on Youtube

Jurgen Welschen
Author by

Jurgen Welschen

Updated on July 17, 2022

Comments

  • Jurgen Welschen
    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
      Poul Kruijt over 8 years
      I'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
    Jurgen Welschen over 8 years
    Thank 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
    Jurgen Welschen over 8 years
    That 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
    Thierry Templier over 8 years
    Yes, 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
    Vlado Tesanovic over 8 years
    No 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
    Motassem Kassab over 7 years
    this totally worked for me with angular 2.0, thanks.