Jayanth Vishwanath
Jayanth Vishwanath

Reputation: 63

@HostBinding disabling class from child component Angular 4

I have an angular app which has user login and logout. I am showing up a welcome page as the home page before a user logs in. I want to enable a background image only on the welcome page. Once the user logs in, the background image must disappear. When the user logs out, he will be redirected to welcome page which must show up the background image again.

I have tried using @HostBinding in the app.component.ts by renaming the selector to 'body'.

app.component.ts

import {Component, HostBinding, Input} from '@angular/core';
import {InputMask} from "primeng/primeng";

@Component({
  selector: 'body',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  path = '../assets/img/AvayaHome.jpg';
  title = 'app';
  toggleClass = true;
  @HostBinding('class.bodyClass') isWelcomePage = this.toggleClass;
}

Here is my CSS.

app.component.css

.bodyClass  {
    background-image: url("../assets/img/AvayaHome.jpg");
}

Here is my index.html

<!doctype html>
<html lang="en">
<head>
 <title> Something </title>
</head>
<body class="bodyClass">

    <app-welcome-page></app-welcome-page>

</body>
</html>

I am enabling the css style for bodyClass by assigning toggleClass as true. Once the user logs in, I am changing the value of toggleClass (which is in the app.component.ts) from the child component.

Here is my login.component.ts

onLogin() {
    console.log('onLogin() invoked:', this._email, ':' , this.password);
    if (this._email == null || this.password == null) {
      this.errorMessage = 'All fields are required';
      return;
    }
    this.errorMessage = null;
    this.loginservice.authenticate(this._email, this.password);
    this.appComponent.toggleClass = true;
    this.router.navigate(['/dashboard']);
  }

The value of the toggleClass changes when the user logs in to FALSE. But I am still seeing the background image. Not sure what I am doing wrong. Any help will be appreciated.

Upvotes: 0

Views: 3527

Answers (4)

yurzui
yurzui

Reputation: 214255

As an example, let's take a look at this code:

var toggleClass = false;
var isWelcomePage = toggleClass;

console.log(isWelcomePage); // prints true

Cool, all works as expected.

Ten seconds later....

Some user logins:

toggleClass = true;

console.log(isWelcomePage); // prints false

Why it has not changed???

If you open any documentation or any book about javascript you can read one main rule:

Primitives are always immutable.

When we assign toggleClass variable to isWelcomePage variable using =, we copy the value to the new variable because primitives are copied by value.

Solution 1:

Change isWelcomePage property directly

onLogin() {
  ...
  this.appComponent.isWelcomePage = true;
  ...
}

Solution 2

Define getter

@HostBinding('class.bodyClass')
get isWelcomePage() {
  return this.toggleClass;
}

Upvotes: 1

anteAdamovic
anteAdamovic

Reputation: 1468

If you want to dynamically display and hide a background you should use a conditional class with ngClass

You can read more about it here NgClass

In your case it would be

<div [ngClass]="{'bodyClass': isWelcomePage}">    
    ...
</div>

Then bodyClass css class will only apply IF isWelcomePage is true, if it's false it won't apply and the image won't show.

Edit:

As requested, a working example: Plunkr

Upvotes: 0

Mike Trinh
Mike Trinh

Reputation: 1303

Make a function with if and else;

if (user is login) {
  document.body.classList.add('bodyClass');
} else {
  document.body.classList.remove('bodyClass');
}

Than call that function when ever you need, logIn logOut etc

Upvotes: 0

Serginho
Serginho

Reputation: 7490

Hostbinding only binds stuff to host tag, in your case tag.

So if you want to manipulate the body tag, you have to do it using plan javascript from your component or also create a component in the body.

@Component({
  selector: 'body',
  template: `<child></child>`
})
export class AppComponent {
  @HostBinding('class') public cssClass = 'class1';
}

Upvotes: -1

Related Questions