0

I'm trying to initialize plugin in parent element through service and then use plugin object in child components. But i have problem that plugin object returns undefined in child components. I believe if i initialize plugin in constructor() then i could access it from child components, but i don't know how to do that.

Parent component

export class HomeComponent implements AfterViewInit {
  constructor(private tooltip: TooltipService) { }

  ngAfterViewInit(): void {
    this.tooltip.initPlugin('.item-tooltip');
  }
}

TooltipService code

@Injectable({
  providedIn: 'root'
})

export class TooltipService {
  public plugin: any;

  constructor() {}

  public initPlugin(elementId: string): void {
    this.plugin = new pluginName(elementId);
  }
}

Child component

export class AccordionComponent implements OnInit {
  constructor(private tooltip: TooltipService) { }

  ngOnInit(): void {
    console.log(this.tooltip.plugin.class);
  }
}

3 Answers3

0
In TooltipService code, your initPlugin function accepting a string parameter.

public initPlugin(elementId: string): void {
    this.plugin = new pluginName(elementId);
  }

But in Parent Component, you are calling initPlugin function without any arguments.

 this.tooltip.initPlugin();

so that's why it return undefined.
SKV
  • 1
  • 1
0

you should use rxjs for this as you're having timing issues where you're accessing it in the child before it's set by the parent, rxjs will solve this once and for all...

import { ReplaySubject } from 'rxjs';

export class TooltipService {
  private pluginSource = new ReplaySubject<any>(1); // use a subject (private)
  plugin$ = this.pluginSource.asObservable(); // public observable

  constructor() {}

  public initPlugin(elementId: string): void {
    this.pluginSource.next(new pluginName(elementId)) // call next on subject to set value
  }
}

in the child, access like:

private sub: Subscription;
ngOnInit(): void {
  // subscribe to observable to receive values, store subscription ref
  this.sub = this.tooltip.plugin$.susbcribe(plugin => console.log(plugin.class));
}

ngOnDestroy() {
  this.sub.unsubscribe(); // always unsubscribe
}
bryan60
  • 28,215
  • 4
  • 48
  • 65
  • Thanks, i had idea using rxjs too, but is there an option to pass elementId to service constructor() so that i could initialize plugin there. – user13762985 Jun 17 '20 at 14:19
  • I don't see why that would change anything... you still have that option... you're getting into things like injector tokens now though which is an entirely different topic and an entirely different question – bryan60 Jun 17 '20 at 14:24
0

It looks like your components are initialized in wrong order.

OnInit is initialized before AfterViewInit. Try to change it ;)

Roberc
  • 1,816
  • 3
  • 9
  • 12