0

I think I'm overlooking something very fundamental, and I've been banging my head for a couple of days now. I'm new to Angular and reactive programming.

So, I have one service and two components.

In my versionService.ts I have a helper method which allows components to set a currentVersion in a _dataStore.

private _dataStore: {
    currentVersion: any
};
currVersionStream$: Subject<Version>;

constructor(public http: Http) {
    this.currVersionStream$ = new BehaviorSubject<Version>(null);
    this._dataStore = {
        currentVersion: null
    };
}
public setCurrentVersion(v: Version): void {
    if (v != null) {
        this._dataStore.currentVersion = v;            
        this.currVersionStream$.next(this._dataStore.currentVersion);
    }
}

Then in my component select-version.component.ts, through a (click) event from the view/template, I use the setCurrentVersion helper method from the VersionService.ts to store the cliked on version.

In select.version.template.html:

<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
    <li *ngFor="#v of availableVersions" (click)="selectedVersion(v)">
        <a href="#">
            Version {{v.versionID}}
        </a>
    </li>
    <li><a href="#">No version</a></li>
</ul>

In version.component.ts: Here I call on the method in the service. Update: I inject versionService in both of my components.

    import {VersionService} from '../../services/services';

@Component({
        selector: 'select-version',
        templateUrl: 'app/component/selectVersion/select-version.template.html',
        providers: [VersionService]
    })

export class SelectVersionComponent implements OnInit {

    constructor(public versionService: VersionService) {}

    public selectedVersion(v: Version) {
        console.log("SVC - set this version: " + v.versionID);
        this.versionService.setCurrentVersion(v);
    }

So, in my second component I want to retrieve the value set/stored in the service (_dataStore), and display it in its view/template (of my second component)

In my second-component.template.html:

<h2>{{selectedVersion}}</h2>

In my second-component.ts: Update:

    import {VersionService} from '../../services/services';

@Component({
    selector: 'main-container',
    templateUrl: 'app/component/mainContainer/main-container.template.html',
    providers: [VersionService],
})

selectedVersion: any;

constructor(public versionService: VersionService) {
    this.versionService.currVersionStream$.subscribe((v) => {
        if(v != null) {
            this.selectedVersion = "Version" + v.versionID
        }
    }, error => console.error (error));
}

Update: In my main component, app.component.ts:

import {SidebarComponent} from './component/sidebar/sidebar.component';
import {MainContainerComponent} from './component/mainContainer/main-container.component';


@Component({
    selector: 'init-app',
    templateUrl: 'app/app-component.template.html',
    directives: [SidebarComponent, MainContainerComponent],
})

export class AppComponent {
    constructor() {}
}

In my boot.ts:

import {bootstrap}    from 'angular2/platform/browser'
import {AppComponent} from './app.component'
import {HTTP_PROVIDERS} from 'angular2/http'

bootstrap(AppComponent, [HTTP_PROVIDERS])
     .catch(err => console.error(err));

What am I missing to be able to view the currentVersion in my template of the second component, and will it update each time a new value is set? Thanks for any reply!

Sojye
  • 175
  • 2
  • 3
  • 9
  • 1
    If you're injecting the service in each component each one will get a different instance. If those components are siblings, make sure to inject the Service in the parent component, once. – Eric Martinez Jan 28 '16 at 13:07
  • 1
    As Eric mentioned, it should be working as you expect. Can you show how you are registering the service with the component? Are you passing it through the `providers` property (i.e. providers: [VersionService]), or are you setting it up when you bootstrap (i.e. bootstrap(AppComponent, [VersionService])? You should be doing the latter only (not both). – Michael Kang Jan 28 '16 at 13:30
  • Ah ok, I was injecting the service in each component. I'll try to inject it in the main component instead. Thanks! – Sojye Jan 28 '16 at 14:18
  • I had the same problem a couple of days ago, it was answered at http://stackoverflow.com/questions/34978455/angular2-cannot-subscribe-to-custom-events-emitted-from-shared-service – stefan Jan 28 '16 at 15:32
  • It is working now! I injected the service in the main component. Thanks! – Sojye Jan 29 '16 at 09:12

1 Answers1

0

To complement what Eric and pixelbits said, you don't share the same instance of the service. One instance is created per component since you use the providers attribute at this level.

If you want to know more about the hierarchical injection, you could have a look at this answer:

Hope it helps you, Thierry

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360