What makes the observable I use in this Angular 11 component return undefined?

What makes the observable I use in this Angular 11 component return undefined?

Problem Description:

I am working on adding a promotions feature to an Angular 11 e-commerce app.

I have a service that makes a get request and reads a JSON containing the campaign’s data.

The service:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Campaign } from '../models/campaign';


@Injectable({
  providedIn: 'root'
})

export class PromoProductsService {

 public apiURL: string;
 public promo$: Observable<Campaign>;
 
  constructor(private http: HttpClient) {
    this.apiURL = `${environment.bffApi}/offer-service`;
    this.promo$ = this.http.get<Campaign>(`${this.apiURL}/campaign`).pipe(shareReplay());
  }
}

NOTE: the campaign JSON contains other (arrays of) "things" the just banners and I would prefer to make a single GET request for all of them. This is why I use promo$: Observable<Campaign>.

In the category component I have:

public getCampaignBanners() {
    this.promoProductsService.promo$.pipe(takeUntil(this.destroyed$)).subscribe((data: any) => {
      this.campaignData = data;
      this.campaignBanners = this.campaignData.campaign.banners;
     
      if (this.campaignBanners && this.campaignBanners.length > 0) {
        this.displayCampaignBanners();
      } 
    });
}

public displayCampaignBanners(){
    this.productList$.pipe(takeUntil(this.destroyed$)).subscribe((productList) => {
      this.campaignBanner = this.campaignBanners.find((banner: any) => {
        return banner.category.toLowerCase() == productLists.category_name.toLowerCase();
      });
    });
}

The problem

Unless I refresh the page after accssing a product list, productList$ is undefined and the the line this.productList$.pipe(takeUntil(this.destroyed$)).subscribe((productList) => { throws a Cannot read properties of undefined (reading 'pipe') error.

Questions:
  1. What am I doing wrong?
  2. What is the easiest way to fix this issue?

Solution – 1

When you call Backend with Angular, you need to subscribe to the observable for get data.

I dont really understand why you create an Observable<Campaign>

    this.http.get<Campaign>(this.apiURL + "/campaign").subscribe(response => {
        console.log(response);
    })

Or something like this if you want to have a method

    public getCampaignBanners() :Observable<Campaign> {
        return this.http.get<Campaign>(this.apiURL + "/campaign");
    }

    // call it after 
    this.promoProductService.getCampaignBanners().subscribe( response => {
        // ...
    })

If you want to handle some error you can do this.

this.http.get<Campaign>(this.apiURL + "/campaign").subscribe(response => {
        console.log(response);
    },
    (error) => {
        console.error(error);
        switch(error.status){
            case 404:
                // 404 code
                break;
            case 500:
                // 500 code
                break;
            default : 
                break
        }
    })

Hope it will help you, maybe it’s not the main problem here, did you try to call your API with POSTMAN or CURL ?
(Sorry for bad english , not native 🙂 )

EDIT


promo: Observable:<any>;

getPromo(){
    if(this.promo == undefined){
        /* Do API CALL and Set promo with Data*/
    }else{
        return this.promo;
    }
}

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject