Home > OS >  How to pass data from parent to child in Angular to change the background color of the child?
How to pass data from parent to child in Angular to change the background color of the child?

Time:04-01

I would like to pass color from parent to child. Then in child component I wanted to access the element itselt to change the background color as follow this.element.nativeElement.style.backgroundColor === this.bgColor;

But there is no change.

child component: event-thumbnail.component.ts

parent component: events-list.component.ts

//event-thumbnail.component.ts

import { Component, ElementRef, Input, OnInit } from '@angular/core';
import { elementAt } from 'rxjs';

@Component({
  selector: 'event-thumbnail',
  template: `
    <div >
      <h2>{{ event.name }}</h2>
      <div>Date: {{ event.date }}</div>
      <div>Time: {{ event.time }}</div>
      <div>Price: $ {{ event.price }}</div>
      <div>
        <span>Location: {{ event.location.address }}</span>
        <span>&nbsp;</span>
        <span>{{ event.location.city }}, {{ event.location.country }}</span>
      </div>
    </div>
  `,
})
export class EventThumbnailComponent implements OnInit {
  @Input() event: any = [];
  @Input() bgColor: string = 'red';

  constructor(public element: ElementRef) {
    console.log(element.nativeElement);
 
  }

  ngOnInit(): void {
    this.element.nativeElement.style.backgroundColor = this.bgColor;
    console.log(this.element.nativeElement.style.backgroundColor); //
  }
}

I am passing color and event from parent as below

//events-list.components.ts

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

@Component({
  selector: 'events-list',
  templateUrl: './events-list.component.html',
})
export class EventsListComponent {
  color = 'black';
  event = {
    id: 1,
    name: 'Angular Connect',
    date: '9/26/2036',
    time: '10:00 am',
    price: 56,
    imageUrl: '/assets/images/angularconnect-shiels.png',
    location: {
      address: '1057 DT',
      city: 'London',
      country: 'England',
    },
  };
}

//events-list.component.html

<div>
  <h1>Upcoming Angular Events</h1>
  <hr />
  <event-thumbnail [bgColor]="color" [event]="event"></event-thumbnail>
</div>

CodePudding user response:

Use [ngStyle] with the input you already have.

<div [ngStyle]="{ backgroundColor: bgColor }">
  <!-- content here -->
</div>

It is an anti-pattern to put logic in a constructor, or to try and access anything using ElementRef except in very specific circumstances.

CodePudding user response:

3 issues that i'm seeing with your code.

  1. in line this.element.nativeElement.style.backgroundColor === this.bgColor; you're not assigning the background color to the element, you should use "=" operator instead of "==="
  2. your input of bgColor value won't be available in the constructor, only on OnInit which happens later
  3. your background won't be changed after the init because it's setting your background only when it's getting initialized.

i would solve it by using ngOnChanges() as following:

export class EventThumbnailComponent implements OnChanges {
  @Input() event: any = [];
  @Input() bgColor: string = 'red';

  constructor(public element: ElementRef) {
  }

  ngOnChanges(changes: SimpleChanges): void {
   if (changes['bgColor']) {
    this.element.nativeElement.style.backgroundColor === this.bgColor;
   }
  }
}

anyways, this is certainly not the best way to achieve what you're trying to, I suggest that you'll take a look on ngStyle directive.

CodePudding user response:

I agree with Gil's answer (https://stackoverflow.com/a/71705766/11022022), but I would try to do it with css only.

In the parent component's css:

.child-container {
    background-color: #whatever;
}

In the child component's css:

:host {
    background-color: inherit;
}

Also take a look at scss for more advanced options, such as variables: https://sass-lang.com/

CodePudding user response:

Input setter is your friend.

          import { Component, Input } from '@angular/core';
        
        @Component({
          selector: 'app-name-child',
          template: '<h3>"{{name}}"</h3>'
        })
        export class NameChildComponent {
          @Input()
          set bgColor(name: string) {
                this._bgColor = name;
          }

private _bgColor: string = 'red';
    
      constructor() {
      }
    
        }

https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter

  • Related