I am practicing with @Input
and @Output
and here is the issue.
In my home component I have the following:
<!-- Main Content -->
<div class="container">
<div *ngIf="registered">
<login></login>
</div>
<div *ngIf="!registered">
<register></register>
</div>
</div>
registered
is located in the HomeComponent.ts
@Component({
selector:'home',
templateUrl:'./home.html',
})
export class HomeComponent {
registered:Boolean = true;
}
My goal is to change the value registered
in the home component depending on what is pressed.
If register is pressed in the navigation bar, the form will change to the register form because the value in the home component
has been changed. However, if login is pressed it goes back.
I made this a little more complicated but this is for learning purposes.
In the directory user
I have three modules, Login
, Register
and UserService
. UserService imports the components from
Loginand
Registerand exports them. I import
UserServiceinto
NavigationBar` module.
In the home.html
page where I want to change the forms I just call <nav-bar></nav-bar>
@NgModule({
imports:[
SmartAdminModule,
UserModule //has Login and Register components
],
declarations: [NavigationBarComponent],
exports: [NavigationBarComponent]
})
export class NavBarModule {
}
I am trying to figure out a way to use either @Output
or @Input
to solve this issue.
This is also on GitHub HERE Any advice with be greatly appreciated.
----------------After some advice from this post this is how I did it but is still not working------------------
I made a UserService
@Injectable()
export class UserService {
public registered: Boolean;
@Output() FormUpdate = new EventEmitter();
public SetUserToRegistered(){
this.registered = true;
this.FormUpdate.emit(this.registered);
}
public SetUserToUnregistered(){
this.registered = false;
this.FormUpdate.emit(this.registered);
}
}
Then I injected it into the home.module.ts
@NgModule({
imports:[
SmartAdminModule,
UserModule,
NavBarModule
],
exports:[HomeComponent],
declarations: [HomeComponent],
providers: [UserService]
})
export class HomeModule {
}
HomeComponent:
@Component({
selector:'home',
templateUrl:'./home.html',
})
export class HomeComponent {
registered: Boolean;
constructor(private userService: UserService) {
this.registered = this.userService.registered;
}
handleFormUpdate(formUpdate){
//what to do here
}
}
Then I had a aha moment and thought I would make the Login
and Register
buttons and inject the userService in there and then that button would be pressed it would change the value of this.registered = this.userService.registered;
in the HomeComponent
NavBar.html
<div>
<button (click)="showRegister()">Register</button>
<button (click)="showLogin()">Login</button>
</div>
NavBarComponent:
@Component({
selector:'nav-bar',
templateUrl:'./navigationBar.html',
})
export class NavigationBarComponent{
constructor (private userService: UserService) { }
showLogin(){
this.userService.registered = true;
}
showRegister(){
this.userService.registered = false;
}
}
home.html
<div class="container">
<div *ngIf="registered">
<login (formUpdate)="handleFormUpdate($event)"></login>
</div>
<div *ngIf="!registered">
<register (formUpdate)="handleFormUpdate($event)"></register>
</div>
</div>
However nothing is happening.
The project is updated on GitHub.
The UserService you have set up is spot on and the best way to manage this variable, I would even go as far as to put the methods that change registered from true to false in the service. That way you know exactly where it is controlled and if you use the flag elsewhere you are not changing that variable on random components.
@Component({
selector:'nav-bar',
templateUrl:'./navigationBar.html',
})
export class NavigationBarComponent{
constructor (private userService: UserService) { }
showLogin(){
this.userService.SetUserToRegistered();
}
showRegister(){
this.userService.SetUserToUnregistered();
}
}
Perhaps the methods could be named different and you can work them in better as you expand your application but it feels like a better approach.
Now you need an observable to monitor that variable, which I wrote in the second part of my answer.
You could even use some rxjs and set the variable up in the service as an observable so that the home component can subscribe to it.
export class HomeComponent implements OnInit {
public registered: boolean = true;
public ngOnInit(): void {
this.userService.RegisteredObservable().subscribe((registered) => {
this.registered = registered;
});
}
}
Then the service could look something like this
import { Injectable } from "@angular/core";
import { BehaviourSubject } from "rxjs/BehaviourSubject";
import { Observable } from "rxjs/Observable";
@Injectable()
export class UserService {
private registered: BehaviorSubject<boolean>;
constructor() {
this.registered = new BehaviourSubject<boolean>();
}
public RegisteredObservable(): Observable<boolean> {
return this.registered;
}
public ChangeRegistered() {
//do stuff
this.registered.next(newRegisteredValue);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With