Search code examples
javascriptangularionic3angular-services

How to return data from a service not a HttpClient to component


I have this service and I need to return the products to components I don't use here the HttpClient or Observable as I don't need them

export class StoreDataProvider {

  private _wooData: any;

  constructor() {
    this._wooData = Woo({
      url: 'http://example.com/',
      consumerKey: 'key here',
      consumerSecret: 'key here',
      wpAPI: true,
      version: 'wc/v3'
    });
  }

  getAllProducts() {
    return this._wooData.get('products', (err, data, res) => {
      return res 
    });
  }

}

The code above returns the headers, not the products but if I console the products inside the service itself instead of return I get the products! the code be will like this:

export class StoreDataProvider {

  private _wooData: any;

  constructor() {
    this._wooData = Woo({
      url: 'http://example.com/',
      consumerKey: 'key here',
      consumerSecret: 'key here',
      wpAPI: true,
      version: 'wc/v3'
    });
  }

  getAllProducts() {
    this._wooData.get('products', (err, data, res) => {
      console.log(res); 
    });
  }

}

The code in the component is just console.log( this._wooService.getAllProducts() ) if I console log at the service

So what am I missing here?


Solution

  • There are a lot of Appraoches of solving this:

    1. Using BehaviorSubject

    import { BehaviorSubject } from 'rxjs';
    
    export class StoreDataProvider {
    
      private _wooData: any;
      private wooData: BehaviorSubject<any> = new BehaviorSubject<any>(null);
      public wooData$ = this.wooData.asObservable();
    
      constructor() {
        this._wooData = Woo({...});
      }
    
      getAllProducts() {
        this._wooData.get('products', (err, data, res) => {
          this.wooData.next(res);
        });
      }
    
    }
    

    And then you can use it in your Component like this:

    constructor(private _wooService: WooService) {}
    
    ngOnInit() {
      this._wooService.wooData$.subscribe(res => console.log(res));
      this._wooService.getAllProducts();
    }
    

    Note that initially you'll get null as we initialized the BehaviorSubject with null. But as soon as you call getAllProducts and receive the data, you're going to get your data.

    2. Using Promise.

    export class StoreDataProvider {
    
      private _wooData: any;
    
      constructor() {
        this._wooData = Woo({...});
      }
    
      getAllProducts(cb) {
        return new Promise((resolve, reject) => {
          this._wooData.get('products', (err, data, res) => {
            if(err) reject(err);
            else resolve(res);
          });
        });
      }
    
    }
    

    And then you can use it in your Component like this:

    constructor(private _wooService: WooService) {}
    
    ngOnInit() {
      this._wooService.getAllProducts()
        .then((res) => console.log(res))
    }
    

    3. Using Callback

    export class StoreDataProvider {
    
      private _wooData: any;
    
      constructor() {
        this._wooData = Woo({...});
      }
    
      getAllProducts(cb) {
        this._wooData.get('products', (err, data, res) => {
          cb(res);
        });
      }
    
    }
    

    And then you can use it in your Component like this:

    constructor(private _wooService: WooService) {}
    
    ngOnInit() {
      this._wooService.getAllProducts((res) => console.log(res));
    }