Miguel Moura
Miguel Moura

Reputation: 39524

Use ngIf with value from child component

Using Angular 8 I have a parent component HTML:

<div>
  <p *ngIf="Condition with value$">Message</p>
  <child></child>
</div>

I need to use ngIf in P tag using value$ that exists on Child Component:

export class ChildComponent implements OnInit {

  value$: Observable<Model>;

  constructor(private service: service) { }

  ngOnInit() {

    this.value$ = // Get value using apiService

  }

}

How can I do this?

Upvotes: 3

Views: 3609

Answers (4)

Dmytro Mezhenskyi
Dmytro Mezhenskyi

Reputation: 265

There are several ways to solve it:

  1. As it was described earlier you can use @Output();
  2. You can access a child component via @ViewChild()
  3. You can write result from API in some property (ex. apiValue) in Service. Then you can inject service to both (parent and child) and track value of 'apiValue'. As Services are mostly singletons - you will get always the same instance with the same value. (It is more flexible way)

Upvotes: 1

MonkeyScript
MonkeyScript

Reputation: 5121

You can use an Output variable in child component to pass data to parent.

child.component.ts :

@Output() changeEvent = new EventEmitter<Model>();

ngOnInit() {
    // Once you subscribe the data from the service, emit an event passing data using event emitter
    this.changeEvent.emit(this.value$);
}

parent.component.html :

<div>
    <p *ngIf="Condition with value$">Message</p>
    <child (changeEvent)="onDataChange($event)"></child>
</div>

parent.component.ts :

// This function will be triggered when the child emits an event and the data will be available as parameter
// Use this data in your condition.
onDataChange(data){
    this.data = data;
}

Demo : https://stackblitz.com/edit/angular-9mms62

Upvotes: 2

Sarah Jung
Sarah Jung

Reputation: 65

You can use @ViewChild. demo here: https://angular-zucwa1.stackblitz.io

parent .ts file

import { Component, ViewChild } from "@angular/core";

@Component({
 selector: "my-app",
 templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular";
  @ViewChild("childComponent", { static: false }) childComponent: any;

  ngOnInit() {

  }
}

parent html file

<hello name="{{ name }}"></hello>
parent component
<p *ngIf="childComponent.value$">
  show according to child value
</p>
<app-child #childComponent></app-child>

Upvotes: 3

Saurabh Yadav
Saurabh Yadav

Reputation: 3386

You can use EventEmitter, Output

Working demo

Parent Component:

<div>
  <p>Parent works</p>
  <p *ngIf="isMessageAvailable">Message depend on child</p>
  <app-child (isAvailable)="onChange($event)"></app-child>
</div>

Parent Class file

import { Component, OnInit } from '@angular/core';

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

  constructor() { }

  ngOnInit() {
  }
  isMessageAvailable: boolean = true;

  onChange(value) {
    this.isMessageAvailable = value;
  }
}

Child Component

<p>
child works!
</p>

<button (click)="valueChanged()">Toogle</button>

Class File:

import { Component, OnInit, EventEmitter, Output  } from '@angular/core';

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

  constructor() { }
  @Output() isAvailable = new EventEmitter();
  childValue: boolean = true;

  ngOnInit() {

  }

  valueChanged() { 
    this.childValue = !this.childValue;
    this.isAvailable.emit(this.childValue);
  }

}

Upvotes: 1

Related Questions