3

I've found some older answers on this, but the methods they use are no longer valid. I have a header component

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx'; 

import { AuthenticationService } from '../_services/Authentication.Service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
  loading = false;
  error = '';
  isLoggedIn = false;
  showMessageWindow = false;
  messageType: string = "";
  messageText: string = "";
  public currentUser: any = null;

  constructor(private _auth: AuthenticationService, private router: Router) { }

  ngOnInit() {
    if(this._auth.isLoggedIn()) {
      this.isLoggedIn = true;
    }
    else {
      this._auth.logout();
      this.isLoggedIn = false;
      this.router.navigate(['/']);
    }
  }

  showMessage(message: string, type: string) {
    this.messageText = message;
    this.messageType = type;
    this.showMessageWindow = true;
  }
}

It's pretty basic, shows and manages what navigation can be seen depending on if and who is logged in. I have a warning/alert built into the header component. Not all pages use the header, so I am importing it into the components that do use it and putting it into the component template by putting <app-header></app-header> at the top.

Here is a component that uses the header.
import { Component, OnInit } from '@angular/core';
import { HeaderComponent } from '../header/Header.Component';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-census',
  templateUrl: './census.component.html',
  styleUrls: ['./census.component.css']
})
export class CensusComponent implements OnInit {

  constructor( private router: Router, private activatedRoute: ActivatedRoute) { }

  ngOnInit() {

  }

}

I want to be able to put a method into this component that makes a call to showMessage() from the header component. I've tried a few different ways with minimal success. My biggest question is how do I reference the embedded component. I looked through the documentation, but they always use a template right into the component and don't use a separate html file.

If I try adding

  @ViewChild(HeaderComponent)
  private header: HeaderComponent;

into my CensusComponent I get a warning:

WARNING in ./src/app/header/Header.Component.ts
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:

2 Answers 2

3

Use the ViewChild decorator factory

// Here is a component that uses the header.

import {ViewChild} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {HeaderComponent} from '../header/Header.Component';
import {Router, ActivatedRoute} from '@angular/router';

@Component({
  selector: 'app-census',
  templateUrl: './census.component.html',
  styleUrls: ['./census.component.css']
})
export class CensusComponent implements OnInit {

  // The argument `HeaderComponent` tells the framework to bind to the child 
  // component whose constructor function is `HeaderComponent`
  @ViewChild(HeaderComponent) header: HeaderComponent;

  constructor(readonly router: Router, readonly activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    this.header.showMessage('an error occurred!', 'error');
  }
}

The error you receive:

WARNING in ./src/app/header/Header.Component.ts
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:

is completely orthogonal.

Specifically, it means that when you imported header/Header.component to register it in your NgModule, you imported the component using a module specifier with different casing. E.g. header/header.component

This is a problem that you can and should fix. Just make sure all imports use the same case.

I recommend using lowercase file names and lowercase module specifiers everywhere. A simple search and replace should take care of it.

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

1 Comment

I've updated my question. I had tried that method, but when I add that in I get the above error.
1

Have you thought about trying to use ViewChild? That should allow you to grab a reference to the header component and call the showMessage() method.

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-view-child

1 Comment

I've updated my question. I did try that, but I get an error when doing so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.