I'm trying to use the same data in ngOnInit
of several components, the problem is, the data are random every time I subscribe to it. I can only subscribe one time in the entire run of the app. That means, if I subscribe twice, it won't have any use because each component will have something else.
I want to subscribe once in a service and to create a global variable.
but when you try to use that global variable in all the components (on ngOnInit
) it is always undefined.
How can I make the components wait for that same thing that can only be called once in the app?
export class UsersService {
public allUsers: Array<Object> = []
public allUsersUrl: string = 'https://glacial-escarpment-40412.herokuapp.com/users/'
constructor(private http: HttpClient) {
this.getAllUsers().subscribe(data => {
this.allUsers = data;
console.log(this.allUsers)
})
}
getAllUsers(): Observable<any> {
return this.http.get<any>(this.allUsersUrl);
}
getUser(id: number): Observable<any> {
return this.http.get<any>(this.allUsersUrl + id);
}
}
My components:
export class FirstComponent {
constructor(private usersService: UsersService){}
ngOnInit() {
console.log(this.usersService.allUsers) //undefined
}
export class SecondComponent {
constructor(private usersService: UsersService){}
ngOnInit() {
console.log(this.usersService.allUsers) //undefined
}
Please help me :)
You have a synchronism problem. This is your scenario
1- create first component
1.1 - injecting UsersService
1.2 - UsersService
request for ASYNC data (execution continues)
2- FirstComponent get and print this.usersService.allUsers
(not still populated because of async request)
3- this.usersService.allUsers
is still undefined
You need Subject Something like this:
UsersService
export class UsersService {
private _allUsersSource = new Subject<Array<Object>>();
private _allUsers$ = this._allUsersSource.asObservable();
public allUsersUrl: string = 'https://glacial-escarpment-40412.herokuapp.com/users/'
constructor(private http: HttpClient) {
this.getAllUsers();
}
getAllUsers(): Observable<any> {
return this.http.get<any>(this.allUsersUrl).subscribe(
data => this._allUsersSource.next(data)
);
}
get allUsers$(): Observable<Array<Object>> {
return this._allUsers$;
}
// OTHERS
}
FirstComponent
export class FirstComponent {
subscription: Subscription;
allUsers: Array<Object>;
constructor(private usersService: UsersService){}
ngOnInit() {
this.subscription = this.usersService.allUsers$.subscribe(users => {
this.allUsers = users;
console.log(this.allUsers);
});
}
Some thing for SecondComponent