0

How to change boolean value from parent component.ts to child component.ts want to show and hide the login and logout option using ngif but not working.I do not know how to set and share boolean value between two components. I am using templateUrl.

app.component.ts:

export class AppComponent { 
public isValid:boolean;
constructor(private router:Router){ 
} 
 logout(){
 localStorage.removeItem('email');
 this.router.navigate(['./login']);
 this.isValid=true; 
 } 
 }

login.component.ts

export class LoginComponent implements OnInit {
public username:string;
public password:string; 
constructor(private router:Router) { } 
ngOnInit() {
} 
userLogin(form:NgForm){ 
if(form.value.username==="admin@gmail.com" && form.value.password==="admin")
 {
  localStorage.setItem('email',form.value.username);
  this.router.navigate(['./php']);
  this.isValid=false;//not working//
} }  }

app.component.html

<ul class="nav navbar-nav navbar-right">
  <li *ngIf="isValid">
    <a [routerLink]="['/login']" >Login</a>
  </li>

  <li *ngIf="!isValid">
      <a (click)="logout()">LogOut</a>
    </li>

</ul>
Apple Orange
  • 646
  • 5
  • 12
  • 27
  • 2
    Possible duplicate of [How do I share data between components in Angular 2?](https://stackoverflow.com/questions/31026886/how-do-i-share-data-between-components-in-angular-2) – Christian Benseler May 30 '18 at 15:03
  • @Christian Benseler:- Not duplicate..Already i have tried that link..but not working properly – Apple Orange May 30 '18 at 15:06

3 Answers3

2

When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should use a shared service. You could either use RXJS BehaviorSubject or Subject for cross component communication.
Subject vs BehaviorSubject

Create a Service

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

    @Injectable()
    export class SharedService {

      private valueSource = new BehaviorSubject<boolean>(false);
      currentValue = this.valueSource.asObservable();

      constructor() { }

     changeValue(value: boolean) {
        this.valueSource.next(value)
      }

    }

Register the service with an Angular module.

why? If we want an instance of a dependency to be shared globally and share state across the application we configure it on the NgModule.

from Angular docs

Angular module providers (@NgModule.providers) are registered with the application's root injector. Angular can inject the corresponding services in any class it creates. Once created, a service instance lives for the life of the app and Angular injects this one service instance in every class that needs it.

@NgModule({
      declarations: [
        AppComponent,


      ],
      imports: [

        BrowserModule,
        BrowserAnimationsModule,

      ],
      providers: [SharedService],
      bootstrap:[AppComponent],

Inject the SharedService in the components
app.component.ts:

export class AppComponent { 
public isValid:boolean;
constructor(private router:Router:private service:SharedService){ 
       this.service.currentValue.subscribe(message => this.isValid = message);//subscribe to the currentValue observable.
} 
 logout(){
 localStorage.removeItem('email');
 this.router.navigate(['./login']);
 this.isValid=true;
 } 

login.component.ts

export class LoginComponent implements OnInit {
public username:string;
public password:string; 
public isValid:boolean;
constructor(private router:Router,private service:SharedService) {}


ngOnInit() {
} 
userLogin(form:NgForm){ 
if(form.value.username==="admin@gmail.com" && form.value.password==="admin")
 {
  localStorage.setItem('email',form.value.username);
  this.router.navigate(['./php']);
  this.isValid=false;
  this.service.changeValue(this.isValid);//it calls next on the BehaviorSubject to change its value.
} }  }
Vikas
  • 11,859
  • 7
  • 45
  • 69
  • Hi if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – Vikas Jun 24 '18 at 18:28
  • shouldn't 'message' in your Service be 'value'? – Matheno Oct 10 '18 at 14:22
0

I do not really understand what is login component designed for, as it is not used anywhere in code provided. Anyway I would strongly suggest to go through basics again. You need to learn more about parent-child component interaction. Here you can find tutorial for that: https://angular.io/guide/component-interaction

0

You must use @Input decorator you code is almost fine just add the followings sentence [isValid]="isLoginValid" and @Input() isValid: any;

HTML App Component

<child-component [isValid]="isLoginValid"><child-component>

child.component.ts

Import {Input} from 'angular/core'

@Input() isValid: any;

....
Abel Valdez
  • 2,368
  • 1
  • 16
  • 33