The TypeError: Property 'subscribe' is not readable because it is undefined

Currently, I am developing an Ionic application and encountered the following method that invokes an observable:

  fetchCountryById(id: number): Promise<Country> {
    return new Promise((resolve, reject) => {
      this.obtainCountries().subscribe(countries => {
        for (let country of countries) {
          if (country.Id == id) {
            resolve(country);
          }
        }
        resolve(undefined);
      }, err => reject(err));
    })
  }

Here is another method in use:

  obtainCountries(): Observable<Country[]> {
    if (this.countries) {
      return Observable.of(this.countries);
    } else if (this.countriesObservable) {
      return this.countriesObservable;
    } else {

      this.storage.get(AppSettings.STORAGE_KEYS.LANGUAGE_APP).then(
        language=>{
          this.countriesObservable = this.http.get(AppSettings.API_URL + 'api/Countries?locale=' + language).map(json => {
            delete this.countriesObservable; // once cached countries are available, we don't need the `countriesObservable` reference anymore
            this.countries = json as Country[];
            this.countries = this.countries.sort(function (a, b) { return (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0); });
            return this.countries;
          }).share();
        }
      ).catch(err=>{
      });

      return this.countriesObservable;

    }

  }

I suspect that I am retrieving incorrect data. Can anyone guide me on how to modify the second method to ensure it returns a valid Observable so that the first method can function properly? I am still getting acquainted with Promises and Observables. Appreciate your assistance.

Answer №1

Issue arises when this.countriesObservable is undefined, and you call this.storage.get(...).then(...). This results in setting this.countriesObservable within the promise callback.

The problem lies in reaching return this.countriesObservable before the execution of the then callback, leading to the return of undefined.

To resolve this, assign this.countriesObservable to a new Observable like a Subject before calling this.storage.get. Then, inside the then, listen to the intended Observable and use its subscribe method to populate this.countriesObservable:

const _subject = new Subject<Country[]>();
this.countriesObservable = _subject;
this.storage.get(AppSettings.STORAGE_KEYS.LANGUAGE_APP).then(
    language=>{
        this.http.get(AppSettings.API_URL + 'api/Countries?locale=' + language).map(json => {
            delete this.countriesObservable; // no need for `countriesObservable` once cached countries are available
            this.countries = json as Country[];
            this.countries = this.countries.sort(function (a, b) { return (a.Name > b.Name) ? 1 : ((b.Name > a.Name) ? -1 : 0); });
            return this.countries;
          }).subscribe(countries => _subject.next(countries));
        }
    ).catch(err=>{});

return this.countriesObservable;

Adjustments may be necessary, but this approach should help address the issue. Hope this solution proves helpful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I attach a cookie to a div that becomes visible after a few seconds of video playback?

After 20 seconds of video play, a div element appears. I am trying to set up a cookie so that once the div is shown, it continues to appear unless the user clears their cache (cookie logic). This is my current attempt - http://jsfiddle.net/9L29o365/ Any ...

Refreshing the page causes Material UI Button to revert to default styling

My question regarding the Material UI Button losing styling after a page refresh (link: Material UI Button loses Styling after page refresh) went unanswered, so I am reposting with a CodeSandbox included for reference: https://codesandbox.io/s/bold-resonan ...

Creating a personalized .hasError condition in Angular 4

I am currently in the process of modifying an html form that previously had mandatory fields to now have optional fields. Previously, the validation for these fields used .hasError('required') which would disable the submit button by triggering a ...

Vue.js encountering an issue of receiving null for the JSON data upon the initial loading phase

Currently, I am expanding my knowledge on vue.js and experimenting with calling a json file to parse the data. Although everything seems to be functioning as intended, whenever I refresh the page, there is a momentary blank screen before the data loads. In ...

Pause Next.js pages temporarily during the build process

Encountering SSR-related issues with certain pages in a Next.js project, causing errors during npm run build and hindering the overall building process: pages/ foo/ bar/ [id].jsx index.jsx index.jsx ... Take for instance, the page ...

What causes the frustratingly slow transition between two components on Android?

I am currently in the process of developing a compact puzzle app that resembles a crossword using Expo, React Native, and Typescript. Below is a concise version of the PuzzleMain component: const PuzzleMain: React.FC<PuzzleMainProps> = ({ navigation ...

Chrome stack router outlet and the utilization of the Angular back button

I'm experiencing an issue with the back button on Chrome while using Angular 14. When I return to a previous page (URL), instead of deleting the current page components, it keeps adding more and more as I continue to press the back button (the deeper ...

Utilizing moment.js to showcase the current time of day

Is there a way to show "Sunday Morning" if it's before noon or "Sunday Afternoon" if it's after noon? This code snippet below is what I am currently using to retrieve the current day: var now = moment().format("dddd"); $("#date").append(now); & ...

React throwing a typescript error while attempting to update state based on the previous state

Hello there! I'm fairly new to working with TypeScript and I've encountered an issue with a piece of state in a child component. I'm trying to modify it based on the previous value, but every time I call the setState function, I get a type e ...

Dygraphs.js failing to display the second data point

My website features a graph for currency comparison using Dygraphs. Everything was working fine until I encountered this strange issue. https://i.stack.imgur.com/OGcCA.png The graph only displays the first and third values, consistently skipping the seco ...

Steps for generating a multer file using a link to an image

My current challenge involves downloading an image from a public URL, converting it into a multer file format, and then uploading it using an existing API. So far, I've experimented with axios using responseType: "blob" and responseType: "arraybuffer" ...

Clicking on multiple instances of the same Vue.js component (popover) results in displaying identical data

Attempting to display an AJAX response in a popover shown by clicking an icon (a custom Vue component) brings about a challenge. The issue arises when there are multiple instances of this component, dynamically rendered through the v-for directive within a ...

Is it possible to utilize an @Input() in Angular with multiple types?

Is it possible for a parent component to pass an object in @Input to the child component that may not always be the same? For instance, can I use: @Input() obj: string | number; In my scenario, I have two different objects as potential inputs: @Input() ob ...

Using ReactJS setInterval with Parameters

One of the functionalities in my code involves setting a time interval based on a specific condition. If the condition is met, the function should continue running until it is no longer true, then it should stop. class TestClassName extends React.Component ...

When sending an HTTP POST request to a Nodejs service with an uploaded file, the request fails after 8-15 seconds on Firefox and 25 seconds on Chrome

My web app is built on Angular 7. I am facing an issue while trying to send larger files to a Node.js service. Smaller files, around 3mb, are being sent successfully but when attempting to send bigger files like 20mb, the request gets cut off. In Chrome, I ...

Dynamically assigning a click function to a method

I'm currently working on a project where I need to create a series of buttons within a table, with each button's functionality dependent on the elements in the same row. <button (click)="(element.method)" mat-raised-button color="warn"> ...

When using REACT to fetch data from an API, the absence of an 'Access-Control-Allow-Origin' header may result in access issues

I am working on a project that involves retrieving products from a company's API. After reaching out to the company, they provided me with the following information: CORS allowed origins for local development is "http://localhost:1229" To adhere t ...

Having trouble getting my parallax slideshow to work with jquery preventDefault

-UPDATE- After countless hours of online courses, tutorials, and programming, I finally completed my website! Check it out here: The site is almost where I want it to be, but there are a few remaining challenges: 1) AJAX: I'm struggling to get the ...

Using jQuery to import an XML node into a document asynchronously

function generateNewMonth(month, year, table) { "use strict"; var url, updatedTable; url = 'newdata.php?m=' + month + '&y=' + year; $.ajax({ type: 'GET', cache: false, url: url, ...

Exploring the functionality of Angular.js through QUnit testing

Is it possible to integrate angular.mock.inject() with QUnit instead of Jasmine? In the provided code snippet, angular.mock.dump is defined, but unfortunately angular.mock.inject remains undefined. <!DOCTYPE html> <html ng-app="mymodule"> & ...