Search code examples
angularundefinedangular8ngoninit

Service class functions return undefined when i use it inside other components in Agular


I am using Angular 8.

I have created a function called getUserInfo() in a service class which returns informations about the user using the cloud service Firestore.

The problem is that when I show the result in the service class, it is defined and works perfectly, but inside the component, the result is undefined.

I think I know what the error is: when I call the function inside the component, it is returning undefined because the function takes some time to retrieve the data from the database, but I don't know how to fix it or what to use instead?

Does RxJS fix it?

I already tried router Resolver but it didn't work either.

This is the function i use in service class

getUserInfo() {
    this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
    return doc.data()
})}

The following is the component where I would like to use the service class function:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth/auth.service';

@Component({
    selector: 'app-super-admin',
    templateUrl: './super-admin.component.html',
    styleUrls: ['./super-admin.component.css']
})
export class SuperAdminComponent implements OnInit {
    user;
    constructor(private authService: AuthService) { }

    ngOnInit() {
        this.user = this.authService.getUserInfo();
    }
}

Solution

  • The better way is to use Rxjs just because it is commonly used with angular so I would definitely recommend that. However if you are looking for solutions without it you can always use Promises.
    So the problem you are facing is that the code is being executed before the data is received from the server. You can remedy that by promisifying your call to firestore inside the service and returning a Promise, then you can invoke the Promise inside your component.
    So the code becomes: The service Class

    getUserInfo() {
    let promise =  new Promise( (resolve,reject) => {
        this.db.collection('users').doc(`${this.cookie.get("id")}`).ref.get().then(doc => {
          resolve(doc.data());
        }).catch(er => {
          reject(er);
        })
    }
    return promise;
    );
    

    Then in the component ts file you can do:

       ngOnInit() {
            this.authService.getUserInfo().then(data => {
              this.user = data;
            });
        }
    

    Hope this helps!