Have some data in a service, and was working perfectly when I had data in an object sitting on the service, but now that I've hooked up a database connection, the data never makes it to the component.
I want the service to subscribe to the data coming back from the database and have defined the call like this:
public setPerson(ac: string): void{
console.log(ac);
this.generatePerson(ac).subscribe((data) => {
// this.mapPersonFromInput(data[0]);
console.dir(data);
});
}
The mapPersonFrominput()
function is a holdover from mocked data. it is essentially the same as extractData further below, but from a static object in the code.
generatePerson looks like this:
public generatePerson(id: string):Observable<Person>{
var datRetUrl: string = '/api/'
var fullUrl: string = datRetUrl + id;
return this.http.get(fullUrl)
.map(this.extractData)
.catch(this.handleError);
}
extractData simply assigns values from the input object to the service's object structure, and handleerror simply logs the error to the console.
I call the service to initialize the data object from the component before the component loads by calling this function from a navigation component:
passCodeToService():void{
this.psn.setPerson(this.accessCode);
this.route.navigate(['/name']);
}
and in the actual component that should get the data, I'm using ngOnInit, but I think I should be using ngOnChanges to initialize the component. Here's the code that I'm currently using, but haven't had luck fixing just yet.
ngOnInit() {
this.name =this.psn.getName();
console.log(this.name);
}
getName()
simply returns the object that I'm storing in the service.
public getName(): Name{
return this.servicePerson.name;
}
You should not use ngOnChanges
here, it is not meant for what you are trying to do.
According to your question, this is what you are trying to achieve:
You can achieve this with the code you have. All you need to do is add a little more code and leverage RxJS. More specifically:
personSubject.next(dataFromDB)
to add to the person stream.With this approach, every time data comes from your DB, that data will be added to a person stream, and anything subscribing to that stream (your component) will get the data.
Quick example (since I don't have your full code):
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class PersonService {
// The person subject
personStream: ReplaySubject<Person> = new ReplaySubject();
// The person observable
person$(): Observable<Person> {
return this.personStream.asObservable();
}
// Get person from DB and add to stream
getDataFromDB() {
this.http.get(url).subscribe(response => {
this.personStream.next(response.person);
});
}
}
@Component({...})
export class MyComponent implements OnInit {
person: Person;
constructor(private personService: PersonService) {}
ngOnInit() {
// Subscribe to person observable. Any time person data changes, this will be called.
this.personService.person$().subscribe(person => this.person = person);
// If you return the `this.http.get(url)` from `getDataFromDB`, you can just do this instead...
this.personService.getDataFromDB().subscribe(person => this.person = person);
}
}
But this is all overkill, because in reality all you need to do is subscribe to the getDataFromDB
function in your component, since that itself can return an observable of Person type.