Consider the utterly simple Angular 2 service:
import { Injectable } from \'@angular/core\';
import {Category} from \"../models/Category.model\";
@Injectabl
Observable
s can be used without much boilerplate using Behavior
s.
@Injectable()
export class CategoryService {
activeCategory:BehaviorSubject<{category:Category}> = new BehaviorSubject({category:null});
// or just `Subject` depending on your requirements
}
@Component({
selector: 'my-selector',
template: `
{{(categoryService.activeCategory | async)?.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
constructor(public categoryService:CategoryService){};
}
You also can just bind to properties of your service
@Component({
selector: 'my-selector',
template: `
{{categoryService?.activeCategory?.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
constructor(public categoryService:CategoryService){};
}
Using the Elvis (or safe-navigation) operator you don't get an error if the activeCategory
only gets a value later, for example when an async call completes.
You may try to substiture ngOnInit()
with ngDoCheck()
. I am not sure (actually I doubt) this is the right thing to do, in any case you can try.
This method is run at every change detection cycle (instead of the standard Angular algorithm I guess, and here is the potential issue) and therefore you shoud have the category
property of MySelectorComponent
up to date with the changes in the service.
Again need to be carefull of side effects (which are not clear to me).
Not too big of a boilerplate chunk. But what's going on here is that when the service is created or you make a call however your want to handle it. Your component will know about it through the subscription and then update your local variable to the new value. Allowing you to access it as this.activeCategory.
import { Injectable } from '@angular/core';
import {Category} from "../models/Category.model";
import {Subscription} from 'rxjs/Subscription';
@Injectable()
export class CategoryService {
private _categoryObject = new Subject<any>();
categoryObjectAnnounced$ = this._categoryObject;
private _activeCategoryObject = new Subject<any>();
activeCategoryObjectAnnounced$ = this._activeCategoryObject;
activeCategory: Category|{} = {};
constructor() {};
}
import { Component, OnInit } from '@angular/core';
import {CategoryService} from "../shared/services/category.service";
import {Category} from "../shared/models/Category.model";
import {Subscription} from 'rxjs/Subscription';
@Component({
selector: 'my-selector',
template: `
{{activeCategory.Name}}<br/>
{{category.Name}}<br/>
`,
})
export class MySelectorComponent implements OnInit {
category:Category|{} = {};
activeCategory:ActiveCategory|{} = {};
activeCategorySubscription : Subscription;
categorySubscription : Subscription;
constructor(public categoryService:CategoryService){
this.categorySubscription= this.categoryService.categoryObjectAnnounced$.subscribe((category) => {
this.category= category;
});
this.activeCategorySubscription= this.categoryService.activeCategoryObjectAnnounced$.subscribe((active) => {
this.activeCategory= active;
});
};
ngOnInit() {
};
}