When an error occurs while trying to execute a promise more than once, the message "Attempting to access an undefined property

Currently, I am tackling asynchronous issues by using promises. The strange thing is that when I run the promise for the first time, everything works perfectly. However, if I execute the same function twice, it throws a "Cannot read property of undefined" error. Reloading the page solves the problem, but it's not ideal for the user to refresh every single time.

I'm trying to understand why this happens. Is the previous promise still in progress? If so, how can I reset or refresh it?

I'm working with Typescript and Angular 4.

Below is the error message:

TypeError: Cannot read property 'ensenanza' of undefined
    at SafeSubscriber._next (notas.service.ts:87)
    (...and more lines of error information...)

And here is the section of code where I'm encountering the issue:

asignatura(key) { //obtain the rbd through cookies
        var cod = [];
        var total_listado = [];
        var prom = Promise;
        return prom.resolve(this.datoCurso(this.key)).then( dcurso => {
            console.log(dcurso);

            this.firebase.list('/sistema/asignaturaRBD').subscribe((asignaturaA) => {

                for (let k = 0; k < asignaturaA.length; k++) {
                    const a = asignaturaA[k];
                    console.log(a.ensenanza +'=='+ dcurso[0].ensenanza +'&&'+ a.nivel +'=='+ dcurso[0].nivel+ '&&'+ a.rbd +'=='+ dcurso[0].rbd);

                    if (a.ensenanza == dcurso[0].ensenanza && a.nivel == dcurso[0].nivel && a.rbd == dcurso[0].rbd) {
                        cod.push({
                            asignatura: a.asignatura,
                            ensenanza: a.ensenanza,
                            nivel: a.nivel})
                            console.log("Passed through if");
                        }
                    }  

                });
                return this.getNombreAsignatura(cod);
            });

        }

Code snippet of datoCurso function:

datoCurso(key) { //retrieve all data by key
            let pushcurso = new Array();

            this.firebase.list('/sistema/curso', {
                query: {
                    equalTo: key,
                    orderByKey: key,
                    limitToFirst: 1
                }
            }).subscribe((datos) => {
                for (let v = 0; v < datos.length; v++) {
                    const c = datos[v];
                    pushcurso.push({
                        ensenanza: c.cod_ensenanza,
                        nivel: c.nivel,
                        rbd: c.rbd
                    });
                    console.log(pushcurso[0].ensenanza+'--'+pushcurso[0].nivel+'--'+pushcurso[0].rbd);
                }
            });
            return pushcurso;
        }

Answer №1

Forget about using promises in this scenario. Instead, create a method called datoCurso that returns an observable containing specific object data:

datoCurso(key)
{
    let pushcurso = new Array();

    this.firebase.list('/sistema/curso', {
        query: {
            equalTo: key,
            orderByKey: key,
            limitToFirst: 1
        }
    }).map((datos: any[]) => datos.map(c => ({
        ensenanza: c.cod_ensenanza,
        nivel: c.nivel,
        rbd: c.rbd
    })));
}

You can then combine two observables and perform your desired operations on the result like so:

Observable.zipArray( // or zipAll - depends on rxjs version
    this.datoCurso(this.key),
    this.firebase.list('/sistema/asignaturaRBD')
).subscribe(([dcurso, asignaturaA]: [any[], any[]]) =>
{
    this.getNombreAsignatura(asignaturaA
        .filter(a => a.ensenanza == dcurso[0].ensenanza && a.nivel == dcurso[0].nivel && a.rbd == dcurso[0].rbd)
        .map(a => ({
            asignatura: a.asignatura,
            ensenanza: a.ensenanza,
            nivel: a.nivel
        })));
});

Disclaimer: I do not fully understand the context of this code, so no guarantees on its correctness.

Answer №2

After some tinkering, I managed to find a solution by replacing promises with setTimeouts.

Here's the revised code:

asignatura(key) { //obtain the RBD from the cookie
        var cod= [];
        var total_listado = [];
        var prom = Promise;
        var dc = this.datoCurso(this.key);
        setTimeout(() => {
        this.firebase.list('/sistema/asignaturaRBD').subscribe((asignaturaA) => {
                for (let k = 0; k < asignaturaA.length; k++) {
                    const a = asignaturaA[k];
                    if (a.ensenanza == dc[0].ensenanza && a.nivel == dc[0].nivel && a.rbd == dc[0].rbd) {
                        cod.push({
                            asignatura: a.asignatura,
                            ensenanza: a.ensenanza,
                            nivel: a.nivel})
                            console.log("Passed through if");
                            //total_listado.push({ key: a.$key, asignatura: a.asignatura, ensenanza: a.ensenanza, estado: a.estado, nivel: a.nivel, rbd: a.rbd })
                        }
                    }  
                });

        }, 3000);
        return this.getNombreAsignatura(cod);

    }


getNombreAsignatura(n){
        var arr = [];
        console.log(n);
        setTimeout(() => {
        this.getAsignatura().subscribe((data)=>{
            for (let i = 0; i < data.length; i++) {
                const asignatura = data[i];
                for (let j = 0; j < n.length; j++) {
                    const cod= n[j];
                    if(asignatura.cod_asignatura == cod.asignatura && asignatura.tipo_ensenanza == cod.ensenanza && asignatura.curso == cod.nivel){
                        arr.push({
                            codigo: asignatura.cod_asignatura,
                            nombre: asignatura.detalle
                        })
                        console.log(asignatura);    
                    }
                }

            }
        });
    }, 5000);
        console.log(arr);
        return arr;
    }

This unconventional approach surprisingly yielded results.

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

Angular2 Collaborative Module

Hey, I've been wondering about something. So, I have a bunch of components that I want to use in various parts of my application. However, rather than loading all these components right from the start, I'd prefer to load them on demand (lazy load ...

What is causing the warnings for a functional TypeScript multidimensional array?

I have an array of individuals stored in a nested associative array structure. Each individual is assigned to a specific location, and each location is associated with a particular timezone. Here is how I have defined my variables: interface AssociativeArr ...

Determining whether a Typescript AST node represents a javascript native function

How can I determine if an AST node in TypeScript represents a valid JavaScript function, as opposed to a custom method? Here's what I'm thinking: function isJavascriptFunction(node: ts.Node): boolean { // ----- } For instance, given the cod ...

An error occurred while trying to assign a value to a property that is undefined in Angular: attempting to set the

I am working with two interfaces export interface ClosureItem{ id:string; name:string; visibility?:boolean; } export interface ClosureAllItems{ [K:string]:ClosureItem; Financials:ClosureItem; Risk:ClosureItem; Iss ...

Which request type is better for load testing a web app: synchronous or asynchronous?

When conducting load testing for a web application, there are two main approaches to consider: Sending synchronous requests in multiple threads. Using an asynchronous client and handling responses in callbacks. With the multi-thread approach, requests w ...

The reason why Type zzz cannot be assigned to type (zzz & NgIterable<xxx>) | undefined | null

Why am I receiving the message in Angular 9 that says: Type Items is not assignable to type (Items & NgIterable) | undefined | null? Despite the fact that the model is correct and there are no errors in the data, I still encounter this TypeScript warn ...

extract data from user input using papaparse

Trying to update a chart with a file from input and parsing it using PapaParse. chart.component.ts: function update_chart(csvdata) { const jsonData = Papa.parse(csvdata); this.data1 = this.prepareData(jsonData.data); const self = this, ...

What steps can be taken to dismiss a "TS2531: Object is possibly 'null'" error as a false positive if the object is always guaranteed to not be null?

Here is the code snippet: const infinoteUrl = $q.localStorage.getItem("infinote-dev-api") === null ? `${window.location.protocol}//${window.location.host}` : $q.localStorage.getItem("infinote-dev-api") console.log(`infinote UR ...

Discovering the category for ethereum, provider, and contract

My current interface looks like this: interface IWeb3 { ethereum?: MetaMaskInpageProvider; provider?: any; contract?: any; }; I was able to locate the type for ethereum using import { MetaMaskInpageProvider } from "@metamask/providers", ...

Assign a value of 0 to the ngModel if it is empty

I am trying to ensure that when the value is null, it defaults to 0. At the moment, I am utilizing Angular PrimeNG components. <p-calendar [(ngModel)]="model.start_time" [timeOnly]="true" placeholder="00:00"></p-calen ...

Error occurred when trying to import an external module using an invalid hook call

I am creating a package named "Formcomponent" using React and React Bootstrap. This code is from index.tsx /** * Renders a component for a form. */ import React from "react"; import Form from "react-bootstrap/Form"; /** * List of props * @returns */ ...

Unspecified type for 'props' parameter - a hurdle in Vue 2's composition API

I've hit a roadblock while attempting to integrate TypeScript into an existing Vue 2.6 project. Unfortunately, I'm required to stick with version 2.6 for legacy reasons. I've gone ahead and installed the composition API as a plugin. The err ...

How does the keyof operator fetch non-enumerable inherited properties from an object literal type?

Take a look at this TypeScript code: 'use strict'; type Value = 1 | 2 ; type Owner = 'ownerA' | 'ownerB'; type ItemType = 'itemTypeA' | 'itemTypeB'; type Item = { type: ItemType; owner: Owner; value: ...

Building a dynamic form in Angular with nested JSON data for enhanced reactivity

Although similar questions have been asked before, I am struggling with a large nested JSON value like the following: "Q-1": { "question": { "text": "What are your hopes and goals for this yea ...

An error occurs when attempting to use object mapping and the rest operator in a return statement due to

I've encountered a type mismatch error in my TypeScript project using Prisma while attempting to return an object with mapped properties in the getPool method. Let's take a look at the code snippet causing the issue: public async getPool({ id, v ...

I'm currently endeavoring to integrate SignalR into my Vue project and encountering an issue

Currently, I am working on a project using Vue with TypeScript and I am interested in integrating SignalR. I have thoroughly studied the documentation provided by '@dreamonkey/vue-signalr' on how to utilize SignalR. import { VueSignalR } from &ap ...

Is there a way to implement imports based on a specific condition?

I'm just starting to learn Angular and TypeScript. My goal is to redirect multiple hostnames to a single Angular 6 project because most aspects are the same, with only language and URLs varying. For example, here's what I have implemented in ap ...

Issue with next.handle not functioning properly in Angular 8 when re-requesting

In the code snippet below, the issue is that even after the token expires (401), the API for fetching the refresh token is called, but the request is not re-sent with the updated token using the inner next.handle(). export class InterceptService implements ...

Error in pagination when using MAX() function in PostgreSQL query

Here is the query I am using to retrieve the latest message from each room: SELECT MAX ( "Messages"."id" ) AS messageId, "Rooms"."id" FROM "RoomUsers" INNER JOIN "Rooms" ON " ...

Utilizing Dependency Injection for Implementation of the Asynchronous ThreadSocketAcceptor

Greetings! I am curious about how the ThreadSocketAcceptor in the QuickFix/n library handles incoming loads without any asynchronous methods. What happens when multiple messages from different initiators pass through the acceptor in various sessions? Are t ...