Troubleshooting: Why is the Array in Object not populated with values when passed during Angular App instantiation?

While working on my Angular application, I encountered an issue with deserializing data from an Observable into a custom object array. Despite successfully mapping most fields, one particular field named "listOffices" always appears as an empty array ([]). This is unexpected since it should contain either one or two elements.

The code snippet within the component that handles this mapping involves nested for loops to iterate through the JSON objects and map their values to properties of a new class instance. It seems like the problem lies in Closure, as I can see the correct values for "officeval" when logged before assigning them to the object.

Although I am aware that performing this deserialization logic within the service might be cleaner, I don't believe it's the cause of the issue. Once I resolve this bug, I plan to refactor the code accordingly.

Below is the method in my component responsible for the subscription:

getContracts() {

  this.contractService.getContracts().subscribe(
    (res) => {

        let officeval = new Array<string>();

        for (var x = 0; x < res.length; x++) {
          for (var z = 0; z < res[x].length; z++) {
             if (res[x][z].resources.office !== undefined){
               for (var a = 0; a < res[x][z].resources.office.values.length; a++) {
                 officeval.push(res[x][z].resources.office.values[a]);
               }
             }
            else {
                  officeval.push("Not a Hive Policy");
                 }

            this.createContract(res[x][z].id, res[x][z].name,"placeholder for type",res[x][z].isEnabled, res[x][z].service,
            officeval, ["q", "w"], ["q", "w"],["q", "w"], ["q", "w"],["q","r"]);

          } console.log(this.contractsList);       
    }
  },
    (err) => console.log(err))
  console.log("logging contracts");
  }

  createContract(id:number, contractName:string, type:string, isEnabled:boolean,
     service:string, listOffices:string[], listRooms:string[],
     listSeats:string[], contractItemsEntries:string[], contractItemsOwners:string[], contractItemsSessions:string[]) {

    this.contractsList.push (new Contract (id, contractName, type, isEnabled,
     service, listOffices, listRooms,
    listSeats, contractItemsEntries, contractItemsOwners, contractItemsSessions ));

  }
}

In the Chrome console, the output sometimes looks like this:

[Contract, Contract, Contract...] x6 
-opened Contract Array:
0:Contact
1:Contract
2:Contract
...
-opened Contract:
listOffices: Array(0) -- ???
listRooms: Array(2) --contain correct values
listSeats: Array(2) --contain correct values
id:1
isEnabled: true
service: contractService
type: "placeholder for type"

Answer №1

We have limited information about your res object, so it's important to verify that

res[x][z].resources.office.values.length > 0

This may be the sole scenario where your officeVal is not populated. (As there is no loop present)

Therefore, I am inclined to believe this is the case.

Answer №2

Upon reviewing the code, it is evident that office.values should have a length of 0, indicating that nothing is being added to it and therefore remains as an Array with a length of 0. To confirm this, please provide the JSON data returned from the getContracts function.

Furthermore, when populating items into the officeval Array, you may observe that it contains more items than expected due to not clearing out officeval in each iteration of the loop. While this could be intentional, my assumption is that it is unintentional.

Answer №3

The primary root cause of the issue stemmed from:

  1. Failure to recognize that javascript passes complex data types by reference (please refer to this insightful article) (I found valuable guidance on addressing pass by value versus pass by reference in these posts: post one, post two)
  2. Omission of resetting the officeval array to 0 after each iteration of the inner for loop

To rectify the situation, I took the following steps:

  1. Repositioned the declaration of the officeval array outside of the outer function to enable reference within the inner function using the this keyword
  2. Utilized the slice method to generate a copy of officeval by value, which was then passed into the inner function for creating new contracts and appending them to the contractsList array.
  3. Immediately reset the value of officeval after adding a new contract to the contractsList.

Below presents the revised version of the code:

officeval: string[] = []

getContracts() {

  this.contractService.getContracts().subscribe(
    (res) => {

        //let officeval = new Array<string>();

        for (var x = 0; x < res.length; x++) {
          for (var z = 0; z < res[x].length; z++) {
             if (res[x][z].resources.office !== undefined){
               for (var a = 0; a < res[x][z].resources.office.values.length; a++) {
                 officeval.push(res[x][z].resources.office.values[a]);
               }
             }
            else {
                  officeval.push("Not a Hive Policy");
                 }

            var testArray = this.officeval.slice(0);

            this.createContract(res[x][z].id, res[x][z].name,"placeholder for type",res[x][z].isEnabled, res[x][z].service,
            testArray, ["q", "w"], ["q", "w"],["q", "w"], ["q", "w"],["q","r"]);

          } console.log(this.contractsList);       
    }
  },
    (err) => console.log(err))
  console.log("logging contracts");
  }

  createContract(id:number, contractName:string, type:string, isEnabled:boolean,
     service:string, listOffices:string[], listRooms:string[],
     listSeats:string[], contractItemsEntries:string[], contractItemsOwners:string[], contractItemsSessions:string[]) {

    this.contractsList.push (new Contract (id, contractName, type, isEnabled,
     service, listOffices, listRooms,
    listSeats, contractItemsEntries, contractItemsOwners, contractItemsSessions ));

    this.offiveval.length = 0;

  }
}

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

Observation reveals a lack of return value

I'm encountering an issue with user sign-in functionality. My setup involves using nativescript-angular in conjunction with a Rails 5 API that utilizes devise_token_auth for authentication. The strange thing is that, despite the server logs indicating ...

Experiencing an issue with Jest - Error: unable to access property 'forEach' of null

After watching some tutorials, I decided to create a sample project in Jest for writing tests. In a TypeScript file, I included a basic calculation function like this: Calc.cs export class Calc { public add(num1: number, num2: number): number { ...

Encapsulating functions with multiple definitions in Typescript

Struggling with wrapping a function that can have multiple return types based on input parameters in Typescript. Imagine wanting a function to return ReturnA for VariantEnum.a and ReturnB for VariantEnum.b. Consider this implementation of sampleFunction: ...

Issue detected: No NgModule metadata was located for 'AppModule' in Angular version 6.1.0

app.module.ts Check out the code snippet below which defines AppModule for an Angular application: import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule } from ...

Having trouble importing the datamap library into the HTML of an Angular 2 application

I am currently in the process of developing a small Angular 2 application for educational purposes, and my intention is to incorporate datamaps for the map interface. However, there is no directive available for this library yet, so I am experimenting wit ...

Upon installation of a new component, Angular components are automatically removed from the system

I am currently working on an asp.net core web application with angular 5 and I need to generate some Barcodes for printing. Fortunately, I came across ngx-barcode, which is a barcode component specifically designed for Angular4+. To install it, I used the ...

billboard.js: The 'axis.x.type' property is conflicting with different data types in this context

axis: { x: { type: "category" } }, An issue has arisen: The different types of 'axis.x.type' are not compatible with each other. The value of 'string' cannot be assigned to '"category" | &qu ...

Uploading multiple strings to an Amazon S3 bucket using Node.js by piping a string

Suppose I have a simple loop similar to the one shown below: for (const i=0; i<3; i++) { to(`This incrementer is ${i}`) } At the end of the loop, I expect my file to contain: This counter is 0 This counter is 1 This counter is 2 I at ...

Error: Unable to assign void to parameter type

Encountering TypeScript Error: Argument type (response: Response<DSBMannschaftDTO[]>) => void is not assignable to parameter type ((value:Response<DSBMannschaftDTO[]>) => (PromiseLike<void> | void)) null | undefined | undefined ...

In the case that the prop is empty or undefined, display an error message before rendering the full component

I am working on an ImageBlock component, which has several props like url, alt, caption, and optionally quality with a default value of 75. The essential prop here is the url. I need a quick way to immediately display an AlertError if the url is not provi ...

Building a continuous timer loop in Angular using RxJS that adapts to changing durations within an array's objects

I am experimenting with a scenario where I read the data, loop based on the duration. For example, starting with "Adam" first, play Adam for a 15-second timer, then move on to the next beginner "Andy" and play Andy for 15 seconds. Once we reach group "int ...

Managing null values in RxJS map function

I'm facing a scenario where my Angular service retrieves values from an HTTP GET request and maps them to an Observable object of a specific type. Sometimes, one of the properties has a string value, while other times it's null, which I want to d ...

Error in Nestjs Swagger: UnhandledPromiseRejectionWarning - The property `prototype` cannot be destructed from an 'undefined' or 'null' object

Currently, I am in the process of developing a Nestjs REST API project and need to integrate swagger. For reference, I followed this repository: https://github.com/nestjs/nest/tree/master/sample/11-swagger However, during the setup, I encountered the foll ...

Inside the function() in angular 2, the value of 'this' is not defined

I've integrated a UIkit confirmation modal into my app. However, I'm encountering an issue when trying to click the <button> for confirmation. The this inside the function is showing up as undefined. Here's the snippet of code in quest ...

Using an object hierarchy in Typescript to create an if statement

Currently, I am attempting to create a logical statement using a hierarchy structure as shown below: if ((config.elementConfig.curve[0].dataset[0].splitBy = 'my discrete var')) {..... However, when implementing this statement, I encounter the er ...

Detecting Changes in the Backend with Angular

I'm curious about the best way to notify the frontend when there is a change in the backend. How can this situation be effectively handled? While developing an application on Azure, I have considered two possibilities, but none of them seem ideal. The ...

Facing issues while trying to update Angular from version 12 to 13 due to conflicting peer dependencies

I'm in the process of upgrading an Angular project from version 12 to 13, following the guidelines provided on the Angular update website https://update.angular.io/?v=12.0-13.0. Before starting the upgrade procedure, this is how the package.json file ...

Is there a way to customize the hover style of Material UI Select or Menu MenuItem using the theme?

The theme I designed import { createMuiTheme } from 'material-ui/styles'; export const MyTheme = createMuiTheme({ palette: { primary: { light: '#757ce8', main: '#3f50 ...

What is the best way to simulate a function within an object using Jest and Typescript?

I am currently working on a function that calls the url module. index.svelte import {url} from '@roxi/routify'; someFunction(() => { let x = $url('/books') // this line needs to be mocked console.log('x: ' + x); }); ...