1

I have 2 components (say component A and component B), which are far off in the component hierarchy. I wish to toggle the visibility of the component A based on an event in the component B. I am trying to pass this state through a service that both the components share.

I tried a few approaches and none of them worked for me. I am not sure whether that is expected or if I am doing something wrong.

ControlService

@Injectable()
export class ControlService {
    public isOpenState: Boolean = false;

    constructor() { }

    enable() {
        this.isOpenState = true;
    }

    disable() {
        this.isOpenState = false;
    }

    isOpen() {
        return this.isOpenState;
    }

}

Approach 1

Component Foo

export class FooComponent implements OnInit {
    private isOpen:Boolean;

    constructor(controlService: ControlService) {
        this.isOpen = controlService.isOpenState;
    }
}

HTML

<div id="wrapper" *ngIf="isOpen"> </div>

Approach 2

Component Foo

export class FooComponent implements OnInit {
    private isOpen:Boolean;
    private controlService: ControlService;

    constructor(_controlService: ControlService) {
        this.controlService = _controlService;
    }

    fetchState(){
    }

    ngOnInit() {
        console.log('Hello Component');
    }
}

HTML

<div id="wrapper" *ngIf="controlService.isOpen()"> </div>

Approach 3

HTML

<div id="wrapper" *ngIf="controlService.isOpenState"> </div>

None of the above are working for me as expected, the state of the component does not reflect the state in the service. Which of these is the right approach, and what am I missing in them? If neither, what is the correct way to go about this?

1
  • Please add the HTML that shows how you use *ngIf. Commented Jun 20, 2016 at 16:45

1 Answer 1

1

Approach 1

export class FooComponent implements OnInit {
    private isOpen:Boolean;

    constructor(controlService: ControlService) {
        this.isOpen = controlService.isOpenState;
    }
}

only updates this.isOpen once. Later updates to controlService.isOpenState won't be updated in FooComponent

Approach 2

should work if your *ngIf looks like

*ngIf="controlService.isOpen()"

Approach 3

should work if your *ngIf looks like

*ngIf="controlService.isOpenState"

The preferred way is using observables instead of plain properties in services so Angular gets notified about updates instead of change detection polling for changes.

For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html

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

2 Comments

My html looks exactly what you have suggested it to be yet, it does not update the state of the component.
I assume you provide ControlService more than once in your application and the component that updates the state, got a different service instance injected than FooComponent. Provide ControlService only once at the root component (AppComponent)

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.