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;
}
If you want to pass data from the child component to the parent component use @Output() and EventEmitter. To pass data from the child to the parent, you have to emit it from the child. The parent will be listening for the event will grab the data.
This is used to get direct access to the element in the DOM and it is not a good practice. However, it is the easiest way to get input data from users and focus on the service itself. Alternatively, use ngModel or consider Angular forms.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With