Perceptible, asynchronous, and various other

After spending an entire day trying to come up with a solution, I've hit a roadblock and now I'm seeking some help.

WHAT I REQUIRE I need to create a service that returns an array of objects. Initially, these objects are fetched from a web service using HttpClient, but I want to store them in a local variable to avoid unnecessary time and bandwidth consumption every time the service is called. Finally, I need to display these objects in a <select *ngFor tag and set a default value once the values are loaded.

INITIAL APPROACH

service.ts

  stati = null;

    getStati() {
      if (this.stati) return this.stati;
      return this.http.get<ApiResponse>(this.apiUrl + 'lists/stati')
        .pipe(
          retry(3),
          map(data => {
            if (data.status === 0)
              this.stati = data.response; // <-- this is an array
            return this.stati;
          }
      ));
    }

request.component.ts

this.svcApi.getStati()
  .subscribe((stati) => {
    this.stati = stati;
    this.request.nascita.stato = 'IT';
    this.request.residenza.stato = 'IT';
  });

request.component.html

<select class="form-control"
        [(ngModel)]="request.nascita.stato" name="stato">
  <option *ngFor="let stato of stati" 
      [value]="stato.codice">{{stato.nome | uppercase}}</option>
</select>

This approach works fine only the first time. However, when my router (re)activates the route, I encounter an error in the component stating that svcApi.getStati().subscribe is not a function; understandably so, as this time it doesn't return an Observable but an array instead!

SECOND ATTEMPT
I attempted to modify the service function like this:

if (this.stati) return Observable.from(this.stati);

But upon returning to the route, I encounter this console error:

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

THIRD ATTEMPT
For my final attempt, I also tried to change

<option *ngFor="let stato of stati | async"

However, this resulted in another error:

ERROR TypeError: Cannot read property 'dispose' of null at AsyncPipe.push

I am confident that there must be a simple solution to this issue, but being new to this, I'm struggling to find it.

Answer №1

As noted in the comment:

Instead of using if (this.stati) return Observable.from(this.stati), consider using if (this.stati) return Observable.of(this.stati)

Although the previous explanation was brief, let's provide some more context:

of(x) is essentially the same as from([x]).

of simply encapsulates any input without altering it - even passing of(of) is valid. On the other hand, from expects the value to be of type

ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;
and attempts to convert the original wrapper into an observable. For example, using from(42) is incorrect, while from('42') works as expected, emitting 4, 2, and then completing. It can be confusing that a string qualifies as an ArrayLike, leading one to mistakenly assume that from functions like of. In my experience, I rarely utilize SubscribableOrPromise<T> with from.

One might naturally assume from is equivalent to of. Personally, I believe there should be a distinct function such as fromArray - especially considering the existence of

fromPromise</code, which lacks laziness. Typically, when utilizing <code>from
, an array is passed in anyway.

Additional Feedback

In its current state, if getStati is invoked multiple times, numerous requests will be sent to the server and the cache will never expire.

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

Tips for converting the iterator from a v-for to a string within a v-if

I am seeking to comprehend how to utilize v-for with v-if's in order to generate repeated teasers without resorting to more simplistic vue-logic. Currently, it appears that when using v-for with v-if nested within, it is not feasible to assign the ind ...

Implementing pagination for an Angular Material table using an HTTP request to set the page

How can I update the table page index when users click on next and previous buttons in an API that fetches data based on a specified Page number? It's important to note that I have already created a shared table. @Input() columns: Column[] = []; @In ...

Utilizing Generic Types in React TypeScript Functional Components

I'm currently developing a TypeScript React component that includes generic type props, so I define the React component as: export interface MyCompProps<T> { items: T[]; labelFunction: (T) => string; iconFunction: (T) => JSX.Element; ...

Rendering a child component in the DOM tree with Aurelia StageComponent

Imagine having an app.html template structured like this: <template> <require from="./MyComponent"></require> <h1>${message}</h1> <my-component>test</my-component> </template> Accompanied by MyCompone ...

Using Ionic's ngmodel directive with a list and associating ids as keys

Having an issue. Trying to connect a toggle button with a list and use the toggle's id as a key. //Function for conversion transform(d) { alert(d); //when i put this.id here i have undefined value return Number(d); } <ion ...

Error: Unexpected token 'export' in NextJS Syntax

A situation has arisen where a library that was functioning perfectly in an app utilizing react-create-app is now needed for use in NextJS (using npx create-next-app --ts). However, upon attempting to integrate the library, an error was encountered: erro ...

Discovering the Solution: Angular 17's Answer to Troubleshooting Peer Dependency Conflicts

After upgrading Angular to version 17 using npm --force, my application was running smoothly in a local environment. However, when attempting to deploy it (via octopus deploy), the npm install process was automatically triggered by .Net, resulting in a lis ...

Is it possible to transform a reference to a React Component into JSON format?

I am looking to serialize the state of a React component into JSON format and save it in a database. Here is the current structure of my code: const [exampleState, setExampleState] = useState([ { componentName: "Test component", co ...

A guide on combining two native Record types in TypeScript

Is it possible to combine two predefined Record types in TypeScript? Consider the two Records below: var dictionary1 : Record<string, string []> ={ 'fruits' : ['apple','banana', 'cherry'], 'vegeta ...

struggling to implement dynamic reactive forms with Angular

Currently, I am experimenting with building a dynamic reactive form using Angular. While I have successfully implemented the looping functionality, I am facing some challenges in displaying it the way I want. <form [formGroup]="registerForm" (ngSubmit) ...

Is there a way to add an event listener to dynamically generated HTML using the v-html directive?

I have a string variable named log.htmlContent that contains some HTML content. This variable is passed into a div to be displayed using v-html. The particular div will only be displayed if log.htmlContent includes an img tag (http: will only be present in ...

Vue.js 3 with TypeScript is throwing an error: "Module 'xxxxxx' cannot be located, or its corresponding type declarations are missing."

I developed a pagination plugin using Vue JS 2, but encountered an error when trying to integrate it into a project that uses Vue 3 with TypeScript. The error message displayed is 'Cannot find module 'l-pagination' or its corresponding type ...

Updating the useClass in providers in Angular depending on the condition: A step-by-step guide

My goal is to dynamically update the service being used based on certain conditions. To achieve this, I have implemented a factory function that calculates and returns the appropriate service. let useClassFactory = ( conn: service1, svc: service2, ob ...

Obtain data from the DOM using ng-select in Angular 10

In my Angular 10 project, I have certain views where I utilize ng-select to showcase and obtain data. The QA team has tests in place that depend on element id and DOM value, specifically designed for basic select elements. With a simple select, we are able ...

How can we transform the output of an API, which includes only a single value, into an object containing just

When working with multiple APIs on the backend, I need to create a front-end using Angular. However, one of the APIs only returns the result ["domain1","domain2"]. To work with this data, I need to transform the list String[] into an array of Domain obje ...

Struggling to access properties of a javascript object while trying to slice it within table pagination

As I work on this program, my goal is to apply a function to an Array of objects to display rows with information from this group of users. However, TypeScript is throwing various errors when I try to access this information. I'm unsure of what I&apos ...

Exploring the integration of Jest with TypeScript

I'm seeking guidance on how to set up TypeScript with Jest. I've scoured numerous resources but haven't found a solution that works for me. Below is my jest.config.js: module.exports = { roots: [ '<rootDir>' ...

I searched through the interface folder in the component.ts file but couldn't locate my typescript property

My coding dilemma goes something like this:- Within the interface folder, I have created a book.ts file with properties. However, my book.component.ts is not recognizing the book.ts property. It seems to work fine when I import the interface (book.ts) dir ...

Is it necessary to alert when there is a collision between a TypeScript type and a constant with the same name in a

     I am encountering an issue with my TypeScript code. Here is a snippet from Project.ts:     import type { SomeType } from '../../types/Project'; // import { SomeType } from '../../types/Project'; tried this too const SomeTyp ...

Encountering difficulty importing TypeScript files dynamically within a Deno executable

When attempting to import a file from aws in an exe using its public link based on user input, I am facing difficulties For example, I generated my exe with the command below deno compile --allow-all main.ts Users execute this exe using commands like ./e ...