goalguy
goalguy

Reputation: 157

Interpolation not working in Angular

I have an Angular project that I am working on and for some reason interpolation is not working in one particular component. I have tried comparing this component with the other components within the project but they are identical. However, it is not working. I have copied the component.ts and component.html files below. What am I doing incorrectly?

members.component.ts

import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
import { moveIn, fallIn, moveInLeft } from '../router.animations';

@Component({
  selector: 'app-members',
  templateUrl: './members.component.html',
  styleUrls: ['./members.component.css'],
  animations: [moveIn(), fallIn(), moveInLeft()],
  host: {'[@moveIn]': ''}
})
export class MembersComponent implements OnInit {

  name: any;
  state = '';
  test = 'test2';

  constructor(public af: AngularFireAuth, private router: Router) {

    this.af.authState.subscribe(auth => {
      if (auth) {
        this.name = af.auth.currentUser;
        console.log('Display Name: ' + this.name.displayName);
      }
    });

  }

  logout() {
     this.af.auth.signOut();
     console.log('logged out');
     this.router.navigateByUrl('/login');
  }

  ngOnInit() {
  }

}

members.component.html

<div class="form-container" id="toolbar">
  <header [@fallIn]="state">
    <button (click)="logout()" class="basic-btn">Logout</button>
  </header>
  <div id="page" [@moveInLeft]="state">
    <h2>Hey {{ this.name.displayname }}!</h2>

    <p>This is a test {{ test }}</p>

    <img src="/src/assets/images/filler.png" />
  </div>

</div>

Upvotes: 1

Views: 13720

Answers (4)

Donald Sanders
Donald Sanders

Reputation: 1

Sometimes it is just a matter of being careful.

As soon as you see that the string interpolation is not working presse F12 (from Chrome) and look at your error messages. If it says something like: ERROR Error: Cannot find control with name: 'Your-Variable-Form-Control-Name-Here'. Then you know that you probably mis-spelled the form variable (or that you used upper-case instead of lower-case). If this is the reason then correct your spelling and like magic the string interpolation will come back.

Upvotes: 0

Joel
Joel

Reputation: 367

I had the same issue on an h2 element and just wrapped *ngIf on the h2 and it worked

Upvotes: 0

SiddAjmera
SiddAjmera

Reputation: 39482

I don't really think that's how you get the currently logged-in user details. These details are present in authState which is a Promise and not an Observable. I wonder how you're able to see the user details in the console.

Also, you're using {{ this.name.displayname }} in the interpolation syntax. You should be using {{ name.displayName}}. The name will initially be undefined. And then once the Promise value is resolved, it will get populated. But till then, the template will start getting rendered. To avoid any errors on the console for that, also place an *ngIf="name" on the wrapping div. Or better, use an async pipe to unwrap the value of authState

Do this in ngOnInit instead of the constructor

import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
import { moveIn, fallIn, moveInLeft } from '../router.animations';

@Component({
  selector: 'app-members',
  templateUrl: './members.component.html',
  styleUrls: ['./members.component.css'],
  animations: [moveIn(), fallIn(), moveInLeft()],
  host: {
    '[@moveIn]': ''
  }
})
export class MembersComponent implements OnInit {

  user;
  state = '';
  test = 'test2';

  constructor(public af: AngularFireAuth, private router: Router) { }

  logout() {
    this.af.auth.signOut();
    console.log('logged out');
    this.router.navigateByUrl('/login');
  }

  ngOnInit() {
    this.user = this.af.authState;
  }

}

In template use

<div 
  class="form-container" 
  id="toolbar" 
  *ngIf="user | async as currentUser">
  <header [@fallIn]="state">
    <button (click)="logout()" class="basic-btn">Logout</button>
  </header>
  <div id="page" [@moveInLeft]="state">
    <h2>Hey {{ currentUser.displayName }}!</h2>
    <p>This is a test {{ test }}</p>
    <img src="/src/assets/images/filler.png" />
  </div>
</div>

without this

Upvotes: 3

Ikhlak S.
Ikhlak S.

Reputation: 9044

I think you are making a asynchronicity call so the template could not retrieve the value since the http request didn't complete.

Wrap your div in an *ngIf statement, and in a template you refer to a variable without using this.:

<div class="form-container" id="toolbar" *ngIf="name">
  <header [@fallIn]="state">
    <button (click)="logout()" class="basic-btn">Logout</button>
  </header>
  <div id="page" [@moveInLeft]="state">
    <h2>Hey {{ name.displayname }}!</h2>

    <p>This is a test {{ test }}</p>

    <img src="/src/assets/images/filler.png" />
  </div>

</div>

Upvotes: 1

Related Questions