0

This question is specific to Angular 2.

http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html

I need to call one of my services, insatiate some objects, and pass them to child controls via injection (I don't want to use a binding for this purpose). How do I do that? In the code below (which does not work) I call blogService to get a CurrentSite object. I need to pass CurrentSite to the NavBar component which is included in the directives attribute of AppComponent.

@Component({
    selector: 'my-app',
    templateUrl: './app/app.html',
    directives: [NavBar, ROUTER_DIRECTIVES],
    providers: [HTTP_PROVIDERS, ROUTER_PROVIDERS, BlogService, provide(CurrentSite, { useExisting: this.CurrentSite })]
})
    @Routes([
        { path: '/', component: Home },
        { path: '/Contact', component: Contact },
        { path: '/Blog', component: BlogIndex }
])
export class AppComponent implements OnInit {
    public CurrentSite: CurrentSite;

    constructor(private blogService: BlogService) {

    }

    ngOnInit()
    {
        this.SetCurrentSite();
    }

    SetCurrentSite()
    {
        this.blogService.GetActiveSites().subscribe(data => {
            let site = data.find(x => x.SiteName === "SamsBlog");

            if (site === null)
                throw new Error("Site SamsBlog was not found");

            this.CurrentSite = new CurrentSite();
            this.CurrentSite.ID = site.ID;
            this.CurrentSite.SiteName = site.SiteName; 
        });
    }
}

1 Answers1

0

You ca create a SessionService that you pass via DI to AppComponent and NavBar.

Once AppComponent retrieves CurrentSite, then is stores CurrentSite in SessionService. NavBar will then be able to access CurrentSite just querying SessionService.

I hope this helps

Picci
  • 16,775
  • 13
  • 70
  • 113
  • Picci, thank you for your reply. How will your suggestion work with regard to timing? I imagine Angular will start rendering child controls immediately or at least long before my service is able to retrieve objects from the database. My child controls will need the passed objects in their constructors in order to render. –  May 17 '16 at 14:36
  • You definetely need to protect your code from CurrentSite being null since it has not yer been retrieved from back end. This can be done either in AppComponent (e.g. via *ngIf you make sure you create NavBar only after CurrentSite has been retrieved) or in NavBar (with a similar mechanism you prevent rendering the parts which depend on CurrentSite being not null). Angular change detection should run afte you update SessionService and therefore should allow rendering after you have created your CurrentSite instance – Picci May 17 '16 at 14:44
  • See also See also [https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service] – Picci May 17 '16 at 14:49
  • Picci, I see the value of your approach and I imagine it will work however it seems to bypass the concept of a hierarchy of injectors as described here: http://victorsavkin.com/post/102965317996/angular-2-bits-unified-dependency-injection. Do I not understand the concept correctly? –  May 17 '16 at 15:49
  • Picci, see also this answer which refers to "hierarchical injectors" http://stackoverflow.com/questions/36109555/how-to-use-dependency-injection-di-correctly-in-angular2 –  May 17 '16 at 15:55
  • I think hierarchical injectors are about giving a limited scope to instances created via DI. In your case my understanding says that you want to share the same instance of CurrentSite among different components. If this is true, you do not need hierarchical DI (rather, it has to be avoided). You just need to pass around THE one instance of CurrentSite which is current. I anticipate that I may have not understood well the point, but I hope this helps – Picci May 17 '16 at 19:33
  • Picci your understanding is correct. The link you provided points me in the right direction, I will pursue it further. Thank you for your answer. –  May 17 '16 at 22:39