Discovering a callback function being executed with an empty array and an undefined variable

Recently, I encountered a peculiar issue after converting a .forEach loop into an actual for loop. The problem arises when I try to push elements into an array, it somehow disrupts the functionality of the .find() method. I am puzzled as to why this is happening because I don't believe I am altering the array in any way; my understanding was that each find operation starts fresh with the original object every time.

I attempted to replicate this problem by creating a simplified version using stackblitz (utilizing combineLatest, for loop with find), but to my surprise, I could not reproduce the error (you need to check the console in the stackblitz). Therefore, I am reaching out in hopes that someone might be able to spot something that I may have overlooked!

https://stackblitz.com/edit/angular-xpzku2

Additionally, it's worth mentioning that the companyList is initialized elsewhere as empty - which is the desired state in this scenario. Although it's not always empty, in this particular context, being empty is essential. Interestingly enough, I only noticed the issue when the list was empty.

Update: I even tried simplifying the process by focusing solely on loops, finds, and pushes, yet the problem persists. Strangely, when I transfer almost identical code to stackblitz, everything functions smoothly. My suspicion now leans towards the record I'm adding, extracted from mstCompanyList populated via spread operator from the observable. At this point, I must admit feeling rather foolish, so any guidance would be highly appreciated! :)

 combineLatest(routesObs, companiesObs, locationsObs, contractorObs).subscribe(([rList, cList, mList, cntList]) => { 
        this.routeList = [...rList];
        this.mstCompanyList = [...cList];
        this.mstLocationList = [...mList];
        this.mstContractorList = [...cntList];

        // Initially, companyList is a properly initialized, empty object.
        console.log(JSON.stringify(this.companyList));

        // Creating a deduplicated version of company List; if the company ID already exists, skip, otherwise add. NOTE: This functioned correctly when it was utilizing .forEach(), unsure why the current implementation is failing.
// The find method begins returning an undefined object for cc during the second iteration (after the first push). Even after removing the entire routeRecord portion, the issue remains persistent; hence, I'm working on narrowing down the problem further.
        for (var x = 0; x < this.routeList.length; x++) {

           // Console logs reveal that routeList stays intact and consistent throughout each iteration.
          console.log(JSON.stringify(this.routeList)); 
          let routeRecord = this.routeList[x];

          // The trouble lies here - the documentation states that find shouldn't execute the callback unless there's an object, yet cc returns undefined. To investigate, I transformed it into a fat arrow function with a console log inside. STRANGELY, THIS BEHAVIOR ONLY OCCURS AFTER THE SUBSEQUENT PUSH, WORKING AS EXPECTED BEFOREHAND.
          let companyExists = this.companyList.find((cc) => { 
            console.log(JSON.stringify(cc));
            return cc.id == routeRecord.companyId 
          });

          // If the company isn't on the list, add it. However, this breaks the previous validation, which forms the core of my dilemma!
          if (companyExists == null) {
            let companyRec = this.mstCompanyList.find(cl => cl.id == routeRecord.companyId);
            this.companyList.push(companyRec);
          }
        }

Answer №1

Upon reviewing your code and the accompanying comments, it appears that you are indicating that this.companyList is initially empty. Subsequently, when you push companyRec onto it, the subsequent call to

this.companyList.find(cc => ...)
returns an undefined value for cc. This suggests that undefined is present in your this.companyList, which implies that the companyRec you pushed is likely undefined.

To address this issue, I recommend verifying the contents of companyRec using

console.log(JSON.stringify(companyRec))
. This will help identify why this.mstCompanyList does not contain a suitable record corresponding to the relevant id, as .find() returns undefined if a matching element is not found.

In the absence of a minimal reproducible example, pinpointing the exact cause is challenging. I advise utilizing the --strictNullChecks compiler option to preemptively detect potential issues with undefined before they manifest at runtime. The compiler should warn you about the omission of a check for undefined prior to executing

this.companyList.push(companyRec)
.

I hope this information proves beneficial to you. Best of luck!

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

There seems to be an issue with the functionality of Angular bindings

Within a form, there is a specific control that looks like this: <select class="form-control" [(ngModel)] ="flightChoice.twoWays" id="twoWays" formControlName="TwoWays"> <option value="false" >one way</option> <option value="t ...

Implementing more stringent type checking in TypeScript instead of utilizing the 'as' keyword

Check out the code snippet below: type DataSets = 'Users' | 'Products' | 'Accounts'; DB.collection('Users' as DataSets).doc(docId).get().then(...) DB.collection('User' as DataSets).doc(docId).get().then(. ...

How to Eliminate Vertical Line in Primeng's Vertical Stepper

https://i.sstatic.net/Y8PQeqx7.pngPresently, I am utilizing primeng vertical stepper. I require assistance in removing the vertical lines for all steps. Attached is a screenshot of the primeng vertical stepper for reference. Is it possible to use ::ng-dee ...

The Angular (click) event requires two clicks in order to trigger the associated Typescript function

I'm facing an issue with a Typescript function that I've linked to (click) in my HTML. Oddly, I have to click the button twice for the function to be executed. Interestingly, if I don't provide any parameters, the function works as expected ...

Modify just one feature of ReplaySubject

I am currently working with a ReplaySubject containing user details of type UserDetails. userData: ReplaySubject<UserDetails>; The UserDetails class includes the following properties, two of which are optional: export class UserDetails { name: ...

Allowing the OPTIONS method in CORS when sending a REST request from AJAX to a WCF Service

After spending 7 hours scratching my head, I am still unable to figure this out. Despite my extensive search on the web, no luck has come my way. My Angular App is sending requests to a WCF command-line hosted service application. To bypass CORS, I utilize ...

Avoiding Redundant HTTP Requests in Angular 2 Template Iterations

In my template, I am using an ngFor to iterate through data received from an asynchronous observable: <div *ngFor="let result of data.results"> <div> <img [src]="parseSrc(result.src)" alt="{{ getCaption(result.id) | async }}" /> ...

Can a constant be utilized as the property name within routerLink when specifying queryParams?

I am currently trying to update the current page by modifying or adding the query parameter "categoryId". When I attempt: <a [routerLink]="" [queryParams]="{ categoryId: category!.id }" queryParamsHandling="mer ...

Typescript is failing to perform type checking

I'm encountering an issue while trying to utilize TypeScript type checking with the following code snippet: abstract class Mammal { abstract breed(other: Mammal); } class Dog extends Mammal { breed(other: Dog) {} } class Cat extends Mammal { ...

Converting JSON HTTP response to an Array in AngularJS 2: A Comprehensive Guide

As I work on a Http get request in Angular 2, the response returned is in JSON format. However, I am facing an issue when trying to use it in a ngFor loop because it is not formatted as an Array. Is there a way to convert JSON data to an Array in Angular ...

obtaining data from an HTML input field

I'm struggling to retrieve the value from an HTML input element, and despite my own research, it seems like I have the correct syntax. However, I'm still unable to get it to work, leaving me confused. When I log the value to the console, it appe ...

Discovering the best method for accessing CSS classes locally within an Angular component

In order to style a 3rd-party component with custom styles, I need to access the dynamically generated css classname from within an angular component. Angular applies transformations to local css classnames for scoping purposes. However, when trying to st ...

Having difficulty retrieving an angular file from a location outside of the asset folder

I'm encountering issues with a small project that is meant to read a log and present it in table format. Here is the outline of the project structure: project structure Within the LOG directory, I should be able to access motore.log from my DataServi ...

Is there a lack of compile checking for generics in Typescript?

Consider the code snippet below: interface Contract<T> { } class Deal<D> implements Contract<D> { } class Agreement<A> implements Contract<A> { } Surprisingly, the following code compiles without errors: let deal:Contract ...

What steps should I take to resolve the issue of my endpoint failing to accept POST requests?

I am in the process of developing a customized API, with an endpoint that is specified as shown below: https://i.stack.imgur.com/sZTI8.png To handle the functionality for this endpoint, I have set up a Profiling Controller. Inside my controller directory ...

Discover the highest value within an array of objects, along with any numerical object attributes that have a value greater than zero

Considering an array of objects structured as follows: [{ "202201": { "WO": 900, "WS": 0, "SY": 0.915, "LY": 0.98, "CT": 75 }, "202202" ...

Design a data structure that encompasses the combined output of multiple functions

I have a set of functions and I want to combine the return types of these functions into a union type. Example Input function types: type InputType1 = () => {type: "INCREASE"} type InputType2 = () => {type: "ADD", by: number} Ou ...

Unable to confirm the validity of an optional FormControl within Reactive Forms

I created a Reactive Form in my Angular application like this: <form [formGroup]="addressForm" (ngSubmit)="submitAddress(stepper)"> <h4>Delivery Address</h4> <hr /> <div class=&qu ...

Unable to utilize external JavaScript files in Angular 8

I've been working on integrating an HTML template into my Angular project and for the most part, everything is going smoothly. However, I've encountered an issue where my JS plugins are not loading properly. I have double-checked the file paths i ...

Is there a way to show a string value stored in Java onto an Angular 8 display?

Hey there! I am just starting out with angular 8 and have a java project where I'm using JDBC to connect to my beloved MySQL database. I have some valuable data stored in a MySQL table that I access in java and store in strings (or even a list). Now, ...