1

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>
2
  • 1
    Are you getting any errors? What is this console.log('Display Name: ' + this.name.displayName); printing to the console? Commented Aug 27, 2018 at 19:32
  • 1
    It is printing the display name correctly. Commented Aug 27, 2018 at 19:49

4 Answers 4

3

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

Sign up to request clarification or add additional context in comments.

4 Comments

I am still having the same issue. The display name gets printed to the console but the template items do not get replaced.
There's also an issue with the case: displayName should be used instead of displayname
Did this fix your issue?
No it did not. Neither displayName nor test are showing. displayName gets printed to the console correctly but it does not appear webpage.
1

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>

2 Comments

I am still having the same issue. The display name gets printed to the console but the template items do not get replaced.
actually, I'm getting the same problem on Angular 6. I wrapped the div in *ngIf, and like you, I see the value on the console, but it does not get rendered on the page. I'm guessing that we've somehow broken the template in the same way.
0

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

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.