Adam Templeton
Adam Templeton

Reputation: 4617

Angular 2 Template not updating

I'm new to Angular 2 and attempting to get a simple project off the ground. It's running inside an embedded Electron browser, if that's at all relevant.

Basically, I just want to call a list of colonists from a service and print them to the page once the call is resolved. However, even though the promise resolves (I've logged out the output to console upon success), the template refuses to update.

I know my syntax is (mostly) correct, because before switching to the mock $Promise, I just set the value directly in ngOnInit() and it displayed just fine.

Any thoughts on where I'm going wrong?

Here is my main App Component:

import { Component } from '@angular/core';
import { OnInit } from '@angular/core';

import { Colonist } from './models/colonist';
import { ColonistService } from './services/colonist.service';

@Component({
    moduleId: module.id,
    selector: 'my-app',
    templateUrl: 'app.component.html',
    providers: [ColonistService]
})
export class AppComponent implements OnInit{
    title: string;
    colonists: Colonist[];

    constructor(private colonistService: ColonistService) {
        this.title = "Steel Saviors";
    }

    ngOnInit(): void {
        this.getColonists();
    }

    getColonists(): void {
        this.colonistService.getAll()
        .then(colonists => {
            console.log("GOT IT: ", colonists);
            this.colonists = colonists;
            console.log("THIS: ", this);
        });
    }

}

My App Module:

// Modules
import { NgModule } from "@angular/core"
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";

// Components
import { AppComponent } from "./app.component";
import { CharacterCreationComponent } from './components/character-creation/character-creation.component'

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [
      AppComponent,
      CharacterCreationComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

My App HTML Template:

<h1>{{title}}</h1>

<li *ngFor="let colonist of colonists">
  {{ colonist.firstName }}
</li>

My Service:

import { Injectable } from '@angular/core';

import { Colonist } from '../models/colonist';

import { COLONISTS } from '../mocks/mock-colonists';

@Injectable()
export class ColonistService {

    getAll(): Promise<Colonist[]> {
        return Promise.resolve(COLONISTS);
    }    
}

And my mock data:

import { Colonist } from '../models/colonist';

export const COLONISTS: Colonist[] = [
    {firstName: 'Alex', lastName: 'Appleton', age: 21},
    {firstName: 'Brandi', lastName: 'Brown', age: 25},
    {firstName: 'Clay', lastName: 'Cassius', age: 32}
]

Upvotes: 1

Views: 2228

Answers (2)

Adam Templeton
Adam Templeton

Reputation: 4617

I figured it out, actually. I forgot one crucial piece of information (my apologies): I'm running the code inside Electron, which appears to require an NgZone run() to refresh from external elements (such as promises).

https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html

Upvotes: 2

John Siu
John Siu

Reputation: 5092

My original guess is the javascript crashed because colonists is undefined when the page is loaded.

So I suggest the following modification:

<h1>{{title}}</h1>

<ul *ngIf="colonists">
<li *ngFor="let colonist of colonists">
  {{ colonist.firstName }}
</li>
</ul>

However, I created a plunker http://plnkr.co/edit/xRMCcB and it work without the above change.

So your code, at least those portion posted, seems working.

Upvotes: 1

Related Questions