Reputation: 1221
I am new to Angular 2+ so I realize I might be going about this the wrong way. I have two components who are siblings. When I click on a "link" in one it redirects to another controller. I want to pass on the object to the component that I am landing on.
This is what I have done so far.
In the first component (building list) I have an event.
public onClick_building(building: Building) {
this._building.addBuilding(building);
this._router.navigate(['/sam/checklistsam']);
}
addBuilding is in a service (building service)
import { Injectable } from '@angular/core';
import { Headers, Http, RequestOptionsArgs, Response, ResponseContentType } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import { ServerService } from './../server-service/server.service';
import { Building } from '../../interfaces/building';
import { FranchiseBuildingFilter } from '../../interfaces/franchise-building-filter';
@Injectable()
export class BuildingService {
public newBuildingIdSubject: Subject<Building> = new Subject<Building>();
private _url = 'building/';
constructor(private http: Http, private _server: ServerService) { }
public addBuilding(building) {
this.newBuildingIdSubject.next(building);
}
}
Then I call for it in component (work with single building page) that I am sent to.
import { Component, AfterViewInit, OnInit } from '@angular/core';
import { Building } from '../../../interfaces/building';
import { BuildingService } from '../../../services/building-
service/building.service';
import { ServerService } from '../../../services/server-service/server.service';
@Component({
selector: 'app-checklist',
templateUrl: './checklist.component.html',
styleUrls: ['./checklist.component.css'],
providers: [BuildingService, ServerService]
})
export class ChecklistComponent implements AfterViewInit, OnInit {
public building: Building;
constructor(private _building: BuildingService) { }
ngOnInit() {
this._building.newBuildingIdSubject.subscribe(res => {
this.building = res;
});
}
How ever this.building is undefined. When I am debugging it doesn't go in to subscribe.
Is there another way to do this or am I missing something?
Thanks in advance!
Upvotes: 1
Views: 781
Reputation: 73357
You have a couple of problems, first of all, your shared service isn't a singleton, so basically it's not a shared service at all. You have provided it in providers array on component level, which means that you have separate instances of services in your components.
You should only add the service as provider in NgModule if you want it as a singleton:
@NgModule({
...
providers: [ BuildingService ] // here!
})
so remove it from components. Also remove ServerService
if it's a similar situation.
@Component({
...
// providers: [BuildingService, ServerService] <-- Remove
})
Second problem, when we have this fixed, is that a Subject
won't work here. Subscription of a Subject
is only fired when it gets an next()
. But as you are calling next()
before navigating to the sibling component, it won't fire in your sibling, since the next()
was already done in the other component before navigating.
You could use a BehaviorSubject
that always emits when there is a subscriber.
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
public newBuildingIdSubject = new BehaviorSubject<Building>(null);
BehaviorSubject
needs an initial value, so make the appropriate initial value you want :)
Upvotes: 1